#include #include #include using namespace std; #define inf 0x3f3f3f constint maxm=10001; int p,s; struct e{int u,v,dis,next; }edge[maxm]; int head[maxm],js; int a,b,c; int que[maxm],begin,tail; int dis[maxm],start; int vis[maxm];
逻辑上还是很简单的,我现在给你讲讲。 初始化就是酱紫: 然后我们读入的x是1,队首元素就是1了。于是我从点1开始遍历,发现了点2可以走,所以我们就到达了这个判断: i f ( d i s [ e d g e [ i ] . v ] > d i s [ q u e [ b e g i n ] ] + e d g e [ i ] . d i s ) ,就是当前的队首元素的dis值加上队首元素的点到当前搜到的点的权值。然后发现比dis[2]小,所以执行判断内部的语句了。 换句话说,就是满足了d i s [ 2] > d i s [ 1 ] 加上 点1到点2的距离。 那么我们就让 d i s [ 2] = d i s [ 1 ] 加上 点1到点2的距离 ,所以dis[2]就从偌大的inf变到了2,再把点2入队,就是执行 q u e [ e n d + + ] = e d g e [ i ] . v 这句到时候再从点2开始找有没有能进一步缩小的。同理,dis[5]也从偌大的inf变成了10,再把点5入队。 当然,点2和点5都要在vis里面记录已经入队了。 点1只能搜到2和5,那么点1的使命到此为止了,我们就把点1出队,就是begin++。 所以第一轮结束的结果就是酱紫,begin指向2,tail指向4: 当然,队列不为空吧。所以继续。 只是我们从点2开始了。 点2就找到了点3,进入判断i f ( d i s [ e d g e [ i ] . v ] > d i s [ q u e [ b e g i n ] ] + e d g e [ i ] . d i s ) ,发现比dis[3]小,于是就让 d i s [ 3] = d i s [ 2 ] 加上 点2到点3的距离。然后让点3入队。当然,点2还找到了点5,哇,又是点5!一样的判断,我们却发现d i s [ 5] 居然大于 d i s [ 2 ] 加上 点2到点5的距离!没法子,那么我dis[5]就要变了!当然是变小!当然,入队还是一样的入队…但是点5已在队列中,所以不需要再一次入队。 所以这一轮结束,就是酱紫: 我们从点5开始继续新一轮搜索,然后搜到了点3,但是d i s [ 3] 然后点3开始搜索,他搜到了点4,所以dis[4]=9 最后,就会是酱紫的结果,点4搜完后,begin和tail的差就变成0了,SPFA算法结束: 最后我们输出dis数组,就可以查看点1到所有点的最短了。 最后给出样例输出: 完整代码如下:
#include #include #include using namespace std; #define inf 0x3f3f3f constint maxm&#61;10001; int p,s; struct e{int u,v,dis,next; }edge[maxm]; int head[maxm],js; int a,b,c; int que[maxm],begin,end; int dis[maxm],start; int vis[maxm];voidaddedge(int u,int v,int dis){edge[&#43;&#43;js].u&#61;u;edge[js].v&#61;v;edge[js].dis&#61;dis;edge[js].next&#61;head[u];head[u]&#61;js;return; }voidspfa(int x){begin&#61;end&#61;1;que[end&#43;&#43;]&#61;x;while(end-begin!&#61;0){//队列不为空执行循环 for(int i&#61;head[que[begin]];i;i&#61;edge[i].next){if(dis[edge[i].v]>dis[que[begin]]&#43;edge[i].dis){dis[edge[i].v]&#61;dis[que[begin]]&#43;edge[i].dis;if(!vis[edge[i].v]){que[end&#43;&#43;]&#61;edge[i].v;vis[edge[i].v]&#61;1;}}} begin&#43;&#43;;}return; }intmain(){cin>>p>>s;for(int i&#61;1;i<&#61;s;i&#43;&#43;){cin>>a>>b>>c;addedge(a,b,c);}memset(dis,inf,sizeof(dis));//初始化dis数组 cin>>start;dis[start]&#61;0;spfa(start);for(int i&#61;1;i<&#61;p;i&#43;&#43;) cout<<dis[i]<<endl;return0; }