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 }
--------------------------------------------------------------------
只有不断学习才能进步!