1. 程式人生 > >利用SPFA算法求最短路

利用SPFA算法求最短路

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 int
g[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算法求最短路