基於bellman-ford演算法使用佇列優化的spfa求最短路O(m),最壞O(n*m)
阿新 • • 發佈:2020-09-19
#include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1e5+10; int n,m; int idx,h[N],ne[N],e[N],w[N],dis[N]; bool st[N]; void add(int a,int b,int W) { e[idx]=b; w[idx]=W; ne[idx]=h[a]; h[a]=idx++; } int spfa() { memset(dis,0x3f,sizeof dis); queue<int>que; dis[1]=0; st[1]=1; que.push(1);//bellman-ford演算法n次迭代,每次更新m條邊。spfa每次更新距離起點最小節點的鄰居節點。 while(que.size()) { auto t=que.front(); que.pop(); st[t]=false; for(int i=h[t];~i;i=ne[i])//節點t的所有臨邊 { int j=e[i],W=w[i];//j是鄰點,W是邊權 if(dis[t]+W<dis[j])//如果鄰點到起點的距離能被佇列中的節點t更新,更新該鄰點,並將該點加入佇列(如果當前佇列沒有該數的話) { dis[j]=dis[t]+W; if(!st[j])//注意節點j可能重複進隊。 { que.push(j); st[j]=1; } } } } if(dis[n]==0x3f3f3f3f)return -1;//本題特殊,說明無負權迴路。 else return dis[n]; } int main() { cin>>n>>m; memset(h,-1,sizeof h); for(int i=0;i<m;i++) { int a,b,c;cin>>a>>b>>c; add(a,b,c); } int t=spfa(); if(t==-1)cout<<"impossible"<<endl; else cout<<t; }