http://acm.hdu.edu.cn/showproblem.php?pid=2544
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
3 2
所谓单元最短路的意思就是:从一个固定的点出发,到达图里的每个点的最短路线的长度。
spfa的伪代码:(1)初始化,源的距离dis[s]设为0;其他点的距离设为INF(无穷大),新建一个队列,将源点s入队,并标记源点s已经在队列中了(2)从队首取出一个top,标记top已经出队,对遍历top所连接的边,如果边k 的另一端的节点b的距离可以更新,即dis[ dege[k].b]>dis[top]+edge[k].dow;则更新dis[ edge[k].b]=dis[top]+edge[k].w,检查吧是否在队列中,如果不在,加入队列。(3)重复执行步骤(2),直到队列为空。
至于链式前向星我想强调一点就是,对于head数组初始化的时候是将其值全部置为-1.
另外还要注意在建立队列的时候 采用的是循环队列,详见代码。
#include <string.h> #include <stdio.h> #include <iostream> #include <queue> using namespace std; const int maxn=1e5+1; const int INF=1e9; struct node { int b; int w; int next; }; node edge[maxn]; int s; int n; int head[maxn]; int que[maxn]; int visit[maxn]; int dis[maxn]; int ip; void add(int u,int v,int c) { edge[ip].b=v; edge[ip].w=c; edge[ip].next=head[u]; head[u]=ip++; } void spfa(int start,int numpoint) { memset(visit,0,sizeof(visit)); for(int i=0;i<=numpoint;i++) dis[i]=INF; int front=-1,tail=-1; dis[start]=0; visit[start]=1; que[++tail]=start; int top,to; int temp; while(front!=tail) { if(++front>numpoint) front-=numpoint;//循环队列 top=que[front]; visit[top]=0; for(int p=head[top];p!=-1;p=edge[p].next) { to=edge[p].b; temp=dis[top]+edge[p].w; if(dis[to]>temp) { dis[to]=temp; if(!visit[to]) { if(++tail>numpoint) tail-=numpoint; que[tail]=to; visit[to]=1; } } } } } int main() { int b,w,m,k; while(~scanf("%d%d",&n,&m)) { if(m==0&&n==0) break; int maxx=-100; memset(head,-1,sizeof(head));//head数组初始化 ip=0; for(int i=1;i<=m;i++) { cin >> k >> b>> w; if(k>maxx) maxx=k; if(b>maxx) maxx=b; add(k,b,w); add(b,k,w); } spfa(1,maxx); printf("%d\n",dis[n]); } return 0; }