最短路 bellman()

  bellman-ford算法用來解決單源最短路徑問題:給定一個起點,求它到圖中全部n個節點的最短路徑ios

  bellman-ford算法的特色是隻對相鄰節點進行計算,能夠避免 Floyd 那種大撒網式的無效計算,大大提升了效率。c++

  

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<bits/stdc++.h>
 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<cnt; 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<iostream>
 2 #include<algorithm>
 3 #include<bits/stdc++.h>
 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<cnt; 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
相關文章
相關標籤/搜索