最短路 Bellman()

  bellman-ford算法用来解决单源最短路径问题:给定一个起点,求它到图中所有n个节点的最短路径

  bellman-ford算法的特点是只对相邻节点进行计算,可以避免 Floyd 那种大撒网式的无效计算,大大提高了效率。

  

 1 #include
 2 #include
 3 #include
 4 using namespace std;
 5 
 6 const int inf = 0x3f3f3f3f;
 7 const int num = ???
 8 struct edge{int u, v, w;}e[???];//边:起点u,终点v,权值(距离)w 
 9 int n, m, cnt;
10 int dis[num];//从规定的起点到一点的距离 
11 int pre[num];//记录前驱节点
12             //eg:pre[x] = y,指从规定的起点到x点的最短路径为 起点->y->x 
13 
14 //打印从s到t的最短路径 
15 void print_path(int s, int t){
16     if(s == t) {printf("%d\n",s); return;}
17     print_path(s, pre[t]);
18     printf("->%d",t);
19 }
20 
21 //
22 void bellman(){
23     int s = 1;    //规定起点为1
24     for(int i=1; i<=n; i++)
25         dis[i] = inf;
26     dis[s] = 0;
27     
28     for(int k=1; k<=n; k++)
29         for(int i=0; i){
30             int x = e[i].u, y = e[i].v, z = e[i].w;
31             if(dis[x] > dis[y] + z){
32                 dis[x] = dis[y] + z;
33                 pre[x] = y;            //如果经过y点到x点距离更短,则更新距离,并记录路径 
34             } 
35         }
36     //print_path(s,?)        如果有需要,打印路径 
37 }
38 
39 int main(){
40     while(~scanf("%d %d", &n, &m) && n && m){
41         cnt = 0;
42         while(m--){
43             int a, b, c;
44             scanf("%d %d %d", &a, &b, &c);
45             e[cnt].u = a;    e[cnt].v = b;    e[cnt].w = c;    cnt++;46             e[cnt].u = b;    e[cnt].v = a;    e[cnt].w = c;    cnt++;
47         }
48         bellman();
49     } 
50     return 0;
51 }

 有判断负圈功能的bellm代码如下

 1 #include
 2 #include
 3 #include
 4 using namespace std;
 5 
 6 const int inf = 0x3f3f3f3f;
 7 const int num = ???
 8 struct edge{int u, v, w;}e[???];//边:起点u,终点v,权值(距离)w 
 9 int n, m, cnt;
10 int dis[num];//从规定的起点到一点的距离 
11 int pre[num];//记录前驱节点
12             //eg:pre[x] = y,指从规定的起点到x点的最短路径为 起点->y->x 
13 
14 //打印从s到t的最短路径 
15 void print_path(int s, int t){
16     if(s == t) {printf("%d\n",s); return;}
17     print_path(s, pre[t]);
18     printf("->%d",t);
19 }
20 
21 //
22 void bellman(){
23     int s = 1;    //规定起点为1
24     for(int i=1; i<=n; i++)
25         dis[i] = inf;
26     dis[s] = 0;
27     int k = 0;            //记录有几轮操作
28     bool update = true;    //判断是否有更新 
29     
30     while(update){
31         k++;
32         update = false;
33         if(k > n){printf("有负圈");return ;}    //有负圈,停止
34         for(int i=0; i){
35             int x = e[i].u, y = e[i].v;
36             if(d[x] > d[y] + e[i].w){
37                 update = true;
38                 d[x] = d[y] + e[i].w;
39                 pre[x] = y;
40             }
41         } 
42     }
43     
44     //print_path(s,?);
45 }
46 
47 int main(){
48     while(~scanf("%d %d", &n, &m) && n && m){
49         cnt = 0;
50         while(m--){
51             int a, b, c;
52             scanf("%d %d %d", &a, &b, &c);
53             e[cnt].u = a;    e[cnt].v = b;    e[cnt].w = c;    cnt++:
54             e[cnt].u = b;    e[cnt].v = a;    e[cnt].w = c;    cnt++;
55         }
56         bellman();
57     } 
58     return 0;
59 }
View Code

 

你可能感兴趣的:(最短路 Bellman())