spfa学习

来源:互联网 发布:在线p图软件 编辑:程序博客网 时间:2024/05/16 14:52

循环的提前跳出:在实际操作中,贝尔曼-福特算法经常会在未达到V-1次前就出解,V-1其实是最大值。于是可以在循环中设置判定,在某次循环不再进行松弛时,直接退出循环,进行负权环判定。具体做法是用一个队列保存待松弛的点,然后对于每个出队的点依次遍历每个与他有边相邻的点(用邻接表效率较高),如果该点可以松弛并且队列中没有该点则将它加入队列中(只有进行松弛操作的点才会对它的邻接点有影响,也就是说其邻接点才需要松弛操作),如此迭代直到队列为空。


#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define maxn 105#define MAXN 1005using namespace std;int n,m,ans,cnt,sx;bool vis[maxn];int dist[maxn],p[maxn];struct Node{int r,cost,next;}edge[MAXN];void init(){memset(vis,0,sizeof(vis));memset(p,0,sizeof(p));memset(dist,0x3f,sizeof(dist));}void addedge(int u,int v,int w){cnt++;edge[cnt].r=v;edge[cnt].cost=w;edge[cnt].next=p[u];p[u]=cnt;}void SPFA(){int i,j,nx;sx=1;queue<int>q;dist[sx]=0;vis[sx]=1;q.push(sx);while(!q.empty()){nx=q.front();vis[nx]=0;q.pop();for(i=p[nx];i;i=edge[i].next){if(dist[edge[i].r]>dist[nx]+edge[i].cost){dist[edge[i].r]=dist[nx]+edge[i].cost;if(!vis[edge[i].r]){vis[edge[i].r]=1;q.push(edge[i].r);}}}}}int main(){int i,j,u,v,w;while(~scanf("%d%d",&n,&m)){init();cnt=0;for(i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);}SPFA();for(i=1;i<=n;i++)printf("i:%d dist:%d\n",i,dist[i]);}return 0;}
7 91 2 32 4 13 4 4 4 6 23 6 86 7 54 5 65 7 71 3 2 

                                             
0 0
原创粉丝点击