SPFA顾名思义就是更快的最短路算法,是Bellman ford算法的优化,SPFA的平均复杂度大约是O(K*|E|),在一般情况下K大约是小于等于2的数,但是总有人对你心怀不轨,构造一组SPFA最坏情形下的数据来卡你,这时候SPFA的复杂度可以达到接近二次指数。SPFA的优点在于可以判断负环,这要从算法的执行方式说起。SPFA的执行过程就是不断地迭代,不断取出队首元素进行松弛直到队列为空。这个做法是是基于三角不等式的,两边之和如果小于第三边则更新第三边的最短路径长度。一个点取出后对其他店进行松弛之后,它可能还会被其他点松弛,再次入队,所以一个点会多次进入队列,如果一个点进入队列的次数大于点的数量,说明存在负环,每次该点都能被松弛并放入队列。所以SPFA有着比dijkstra独特的优势。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define mp(a,b) make_pair((a),(b)) 17 #define P pair<int,int> 18 #define dbg(args) cout<<#args<<":"<<args<<endl; 19 #define inf 0x3f3f3f3f 20 const int maxn=10010; 21 int n,m,t,e; 22 int head[maxn],nxt[maxn],d[maxn],in[maxn]; 23 struct node{ 24 int v,w; 25 }p[maxn]; 26 void init() 27 { 28 e=0; 29 mem(head,-1); 30 mem(nxt,-1); 31 } 32 void addedge(int u,int v,int w) 33 { 34 p[e].v=v; 35 p[e].w=w; 36 nxt[e]=head[u]; 37 head[u]=e++; 38 } 39 void spfa(int src) 40 { 41 f(i,1,n)d[i]=inf; 42 d[src]=0; 43 mem(in,false); 44 queue<int>q; 45 in[src]=1; 46 q.push(src); 47 while(!q.empty()) 48 { 49 int now=q.front(); 50 q.pop(); 51 in[now]=0; 52 for(int i=head[now];~i;i=nxt[i]) 53 { 54 if(d[p[i].v]>d[now]+p[i].w)//松弛 55 { 56 d[p[i].v]=d[now]+p[i].w; 57 if(!in[p[i].v]) 58 { 59 q.push(p[i].v); 60 in[p[i].v]=1;//不在队列中就入队 61 } 62 } 63 } 64 } 65 } 66 int main() 67 { 68 //freopen("input.txt","r",stdin); 69 //freopen("output.txt","w",stdout); 70 std::ios::sync_with_stdio(false); 71 while(scanf("%d%d",&n,&m)==2&&!(n==0&&m==0)) 72 { 73 int u,v,w; 74 init(); 75 f(i,1,m) 76 { 77 scanf("%d%d%d",&u,&v,&w); 78 addedge(u,v,w); 79 addedge(v,u,w); 80 } 81 spfa(1); 82 pf("%d ",d[n]); 83 } 84 }