您的位置:首页 > 其它

poj 2387 Til the Cows Come Home spfa基础题,入门,我的第一个

2011-11-26 02:11 387 查看
终于想到spfa的好处了,首先要比dij快啊!!dij是所有点汤一遍,而spfa用链表有方向的,还有dij遇见负权边就完了
dijkstra不能有负权边,否则结果是错的,你想想,假如无向图有1,2,3个点,w(1,2)=1,w(1,3)=2,w(2,3)=-2.按dij算法求求看。
实现方法:建立一个队列,初始时队列里只有起始点,在建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点去刷新起始点到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空
判断有无负环:如果某个点进入队列的次数超过N次则存在负环
存在负权回路的图是不能求两点间最短路的,因为只要在负权回路上不断兜圈子,所得的最短路长度可以任意小。
#include<iostream>
usingnamespacestd;
#include<algorithm>
#include<queue>
#defineN10005
#defineinf0x7FFFFF
structnode
{
intu;
intc;
intnext;
}e
;
intd
,p
;
boolvis
;
intspfa(ints)
{
d[s]=0;
// vis[s]=true;
queue<int>q;
q.push(s);
while(!q.empty())
{
intt=q.front();
q.pop();
vis[t]=false;
for(intj=p[t];j!=-1;j=e[j].next)//这是想大于有方向的爬树,比dij快多了
{
intw=e[j].c;
inttemp=e[j].u;
if(w+d[t]<d[temp])
{
d[temp]=w+d[t];
if(!vis[temp])//防止出现环,也就是进队列重复了
{
vis[temp]=true;
q.push(temp);
}
}
}
}
}

intmain()
{
intt,n,a,b,c;
while(cin>>t>>n)
{
memset(p,-1,sizeof(p));
memset(vis,false,sizeof(vis));
fill(d,d+N,inf);
inttemp=0;
while(t--)
{
scanf("%d%d%d",&a,&b,&c);//双向链表
e[temp].u=b;
e[temp].c=c;
e[temp].next=p[a];
p[a]=temp;
temp++;
e[temp].u=a;
e[temp].c=c;
e[temp].next=p[b];
p[b]=temp;
temp++;
}
spfa(1);
cout<<d
<<endl;
}
return0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: