最短路径算法二

最短路径算法2——Bellman-Ford与SPFA算法

Bellman-Ford算法:

只能计算单源最短路径,时间复杂度为O(nm)n是顶点数,m是边数。

其实这个算法很简单,代码实现也很简单,大致和Floyed差不多吧。

循环n-1次,每次循环遍历所有边,必然会有一些边连接着蓝点与白点。因此每次都能用所有的白点去修改所有的蓝点。所以这个算法只是理论模拟了蓝点白点,并没有真正实现。

Bellman-Ford代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #define N 42000
 4 using namespace std;
 5 int n,m,p,q,a[N],b[N],c[N],d[N];
 6 int main(){
 7     scanf("%d%d%d%d",&n,&m,&p,&q);
 8     for(int i=1;i<=m;++i)
 9         scanf("%d%d%d",&a[i],&b[i],&c[i]);
10     for(int i=1;i<=n;++i)
11         d[i]=42000000;
12     d[p]=0;
13     for(int i=1;i<n;++i)
14         for(int j=1;j<=m;++j)
15             d[b[j]]=min(d[b[j]],d[a[j]]+c[j]);
16     printf("%d",d[q]);
17     return 0;
18 }
View Code

SPFA算法:

SPFA算法是Bellman-Ford算法的一种队列实现,减少了不必要的冗杂计算,时间复杂度为O(km)m是边数,k是常数,平均值为2.

基本思路是初始将起点加入队列,每次从队列取出一个元素,并对所有和它相连的节点进行修改,若修改某个点成功,将这给点入队,直到队列为空。

SPFA代码:

 1 #include<queue>
 2 #include<cstdio>
 3 #define N 42000
 4 using namespace std;
 5 queue<int>h;
 6 int next[N],to[N],dis[N],num,head[N],n,m,p,q,a,b,c,d[N],u,boo[N];
 7 void add(int false_from,int false_to,int false_dis){
 8     next[++num]=head[false_from];
 9     to[num]=false_to;
10     dis[num]=false_dis;
11     head[false_from]=num;
12 }
13 int main(){
14     scanf("%d%d%d%d",&n,&m,&p,&q);
15     for(int i=1;i<=m;++i){
16         scanf("%d%d%d",&a,&b,&c);
17         add(a,b,c);
18         add(b,a,c);
19     }
20     for(int i=1;i<=n;++i)
21         d[i]=42000000;
22     d[p]=0;
23     h.push(p);
24     do{
25         u=h.front();
26         h.pop();
27         boo[u]=0;
28         for(int v=head[u];v;v=next[v])
29             if(d[u]+dis[v]<d[to[v]]){
30                 d[to[v]]=d[u]+dis[v];
31                 if(!boo[to[v]]){
32                     h.push(to[v]);
33                     boo[to[v]]=1;
34                 }
35             }
36     }while(!h.empty());
37     printf("%d",d[q]);
38     return 0;
39 }
View Code

 

posted @ 2017-05-07 19:23  江屿  阅读(220)  评论(0编辑  收藏  举报