wenbao与最短路(Floyd)

 Floyd算法堪称经典。仅仅五行代码就可以求出多源最短路,建议好好思考为什么可以这样求

 

注意点:中转点k在最外层循环,这样可以确保【i】【k】,【k】【j】最小 

1 for k = 1 .. N
2     for i = 1 .. N 
3         for j = 1 .. N
4             若i, j, k各不相同
5                 MinDistance[i, j] = min{MinDistance[i, j], MinDistance[i, k] + MinDistance[k, j]}

 

1 for(int k=1; k<=n; k++)               //Floyd求任两点之间的最短路径
2     for(int i=1; i<=n; i++)
3         for(int j=1; j<=n; j++)
4             a[i][j] = min(a[i][j], a[i][k] + a[k][j]);

 

 膜拜大神:

1 for (k = 1; k <= n; ++k)    for (j = 2; j <= n; ++j){
2   edge[j][j] = 0;
3   for (i = 1; i < j; ++i)    if (k != i && k != j){
4    value = edge[i][k] + edge[k][j];
5    edge[j][i] = edge[i][j] = (edge[i][j] > value ? value : edge[i][j]);
6     }
7}

 

 

矩阵对角优化,下三角,不存在路径优化,数学函数优化

 

 1 void floyd() {
 2     for (int k = 1; k <= n; k++) {
 3         for (int i = 1; i <= n; i++) {
 4             if (k != i) {
 5                 const int a_ki = (k < i) ? a[i][k] : a[k][i];
 6                 // skip if no path
 7                 if (a_ki == INF) continue;
 8                 const int tt = (k < i) ? k : i;
 9                 for (int j = 0; j < tt; j++) {
10                     const int s_kj = a_ki + a[k][j];
11                     if( s_kj < a[i][j] ) a[i][j] = s_kj;
12                 }
13                 for (int j = k + 1; j < i; j++) {
14                     const int s_jk = a_ki + a[j][k];
15                     if( s_jk < a[i][j] ) a[i][j] = s_jk;
16                 }
17             }
18         }
19     }
20 }

 

 

 

--------------------------------------------------------------

 

 

http://hihocoder.com/problemset/problem/1089

 

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 #define INF 123456789
 6 long long a[1005][1005];       //任意两点间的最短路径长度
 7 
 8 int main(){
 9 //  freopen("in.txt","r", stdin);
10     int n, m, x, y, t;
11     while(scanf("%d%d", &n, &m)!=EOF){
12         for(int i=1; i<=m; i++)
13             for(int j=1; j<=n; j++){
14                 a[i][j] = INF;
15                 if(i == j) a[i][j] = 0;
16             }
17         for(int i=1; i<=m; i++){
18             scanf("%d%d%d", &x, &y, &t);
19             if(a[x][y] > t)  a[x][y] = a[y][x] = t;
20         }
21 
22         for(int k=1; k<=n; k++)               //Floyd求任两点之间的最短路径
23             for(int i=1; i<=n; i++)
24                 for(int j=1; j<=n; j++)
25                     a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
26 
27 
28         for(int i=1; i<=n; i++){
29             for(int j=1; j<=n; j++){
30                 if(j>1) printf(" ");
31                 printf("%lld", a[i][j]);
32             }
33             printf("\n");
34         }
35     }
36     return 0;
37 }

 

 

大神代码

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 int edge[101][101];
 4 int main()
 5 {
 6     int m, n, from, to, value, i, j, k;
 7     scanf("%d%d", &n, &m);
 8     memset(edge, 0x3f, 101 * 101 * sizeof(int));
 9     for (i = 0; i < m; ++i)
10     {
11         scanf("%d%d%d", &from, &to, &value);
12         if (edge[from][to] > value)
13             edge[from][to] = edge[to][from] = value;
14     }
15     for (k = 1; k <= n; ++k)
16         for (j = 2; j <= n; ++j)
17         {
18             edge[j][j] = 0;
19             for (i = 1; i < j; ++i)
20                 if (k != i && k != j)
21                 {
22                     value = edge[i][k] + edge[k][j];
23                     edge[j][i] = edge[i][j] = (edge[i][j] > value ? value : edge[i][j]);
24                 }
25         }
26     edge[1][1] = 0;
27     for (i = 1; i <= n; ++i)
28     {
29         for (j = 1; j < n; ++j)
30             printf("%d ", edge[i][j]);
31         printf("%d\n", edge[i][j]);
32     }
33     return 0;
34 }

 

 

 1 #include "iostream"
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int maxn = 111;
 6 int a[maxn][maxn], n, m, x, y, z;
 7 #define INF 1e9
 8 
 9 void floyd() {
10     for (int k = 1; k <= n; k++) {
11         for (int i = 1; i <= n; i++) {
12             if (k != i) {
13                 const int a_ki = (k < i) ? a[i][k] : a[k][i];
14                 // skip if no path
15                 if (a_ki == INF) continue;
16                 const int tt = (k < i) ? k : i;
17                 for (int j = 0; j < tt; j++) {
18                     const int s_kj = a_ki + a[k][j];
19                     if( s_kj < a[i][j] ) a[i][j] = s_kj;
20                 }
21                 for (int j = k + 1; j < i; j++) {
22                     const int s_jk = a_ki + a[j][k];
23                     if( s_jk < a[i][j] ) a[i][j] = s_jk;
24                 }
25             }
26         }
27     }
28 }
29 
30 int main() {
31 #ifdef wenbao
32     freopen("in", "r", stdin);
33 #endif
34     scanf("%d%d", &n, &m);
35     for(int i = 1; i <= n; ++i){
36         for(int j = 1; j < i; ++j){
37             a[i][j] = a[j][i] = INF;
38         }
39     }
40     for(int i = 0; i < m; ++i){
41         scanf("%d%d%d", &x, &y, &z);
42         if(z < a[x][y]) a[x][y] = a[y][x] = z;
43     }
44     floyd();
45     for(int i = 1; i <= n; ++i){
46         for(int j = 1; j <= n; ++j){
47             printf("%d%c", i >= j ? a[i][j]: a[j][i],  " \n"[j == n]);
48         }
49     }
50     return 0;
51 }

 

--------------------------------------------------------------------

 

 

只有不断学习才能进步!

 

posted @ 2018-04-14 13:55  wenbao  阅读(109)  评论(0编辑  收藏  举报