利用SPFA算法求最短路
阿新 • • 發佈:2018-07-06
while nbsp cout poi 操作 沒有 實際應用 a算法 ()
該算法由Bellman-Ford算法演變過來,首先介紹一下Bellman-Ford算法
最短路最多經過n-1個點,可以用n-1輪松弛操作來得到
for(int i=0;i<n;i++) d[i]=INF; d[0]=0; for(int k=0;k<n-1;k++) for(int i=0;i<m;i++) //檢查每條邊 { int x=u[i]; int y=v[i]; if(d[x]<INF) d[y]=min(d[y],d[x]+w[i]); }
當然這個算法我沒有實際應用過,而是一直在用它的優化算法,利用隊列代替前面的循環檢查
SPFA最壞時間復雜度仍然為O(nm),但是有人分析其時間復雜度為O(km),k為每個點入隊次數,正確性未知
SPFA和Bellman-Ford都可以檢測負環但是只有後者可以輸出負環
下面給出鄰接表實現的SPFA算法,可以求出單源最短路。
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxn=10005; 5 const int maxm=500005; 6 const int INF=0x7fffffff; 7 // 8 int n,m,s; 9 // 10 intg[maxn]; 11 struct point 12 { 13 int t,w,next; 14 }e[maxm]; 15 int d[maxn]; 16 // 17 int tot=0; 18 void addedge(int a,int b,int c) 19 { 20 tot++; 21 e[tot].t=b; 22 e[tot].w=c; 23 e[tot].next=g[a]; 24 g[a]=tot; 25 } 26 // 27 int q[maxn]; 28 bool v[maxn]; 29 void spfa(int x0) 30 { 31 for(int i=1;i<=n;i++) 32 d[i]=(i==x0?0:INF); 33 int h=0,t=1; 34 q[t]=x0; 35 while(h!=t) 36 { 37 h=h%maxn+1; 38 int x=q[h]; 39 v[x]=false; 40 for(int tmp=g[x];tmp;tmp=e[tmp].next) 41 { 42 if(d[e[tmp].t]>d[x]+e[tmp].w) 43 { 44 d[e[tmp].t]=d[x]+e[tmp].w; 45 if(!v[e[tmp].t]) 46 { 47 v[e[tmp].t]=true; 48 t=t%maxn+1; 49 q[t]=e[tmp].t; 50 } 51 } 52 } 53 } 54 } 55 int main() 56 { 57 cin>>n>>m>>s; 58 for(int i=1;i<=m;i++) 59 { 60 int x,y,z; 61 cin>>x>>y>>z; 62 addedge(x,y,z); 63 } 64 spfa(s); 65 for(int i=1;i<=n;i++) 66 cout<<d[i]<<" "; 67 return 0; 68 }
利用SPFA算法求最短路