hdu2544SPFA板题

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  } 
原文地址:https://www.cnblogs.com/randy-lo/p/12552127.html