5 0 3 22 -1 4 3 0 5 -1 -1 22 5 0 9 20 -1 -1 9 0 4 4 -1 20 4 0 5 17 8 3 1 1 3 3 5 2 4 -1 -1 0
From 1 to 3 : Path: 1-->5-->4-->3 Total cost : 21 From 3 to 5 : Path: 3-->4-->5 Total cost : 16 From 2 to 4 : Path: 2-->1-->5-->4 Total cost : 17
floyd 最好用 因为此题要输出路径。。。
AC代码
#include<cstdio> #include<cstring> #include<cmath> #include<stack> #include<queue> #define mem(a, b) memset(a, (b), sizeof(a)) #define Wi(a) while(a--) #define Si(a) scanf("%d", &a) #define Pi(a) printf("%d\n", (a)) #define INF 0x3f3f3f3f #include<algorithm> using namespace std; const int N = 500; int map[N][N], path[N][N], b[N]; int n; void input() { int i, j, k; for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { Si(map[i][j]); if(map[i][j] == -1) map[i][j] = INF; path[i][j] = j; } } for(i = 1; i <= n; i++) Si(b[i]); } void floyd() { int i, j, k; for(k = 1; k <= n; k++)//k中转点 { for(i = 1; i <= n; i++)//i起点 { for(j = 1; j <= n; j++)//j终点 { if(map[i][j] > map[i][k] + map[k][j] + b[k]) { map[i][j] = map[i][k] + map[k][j] + b[k]; path[i][j] = path[i][k]; } else if(map[i][j] == map[i][k] + map[k][j] + b[k]) { if(path[i][j] > path[i][k]) { path[i][j] = path[i][k]; map[i][j] = map[i][k] + map[k][j] + b[k]; } } } } } } void put_path(int u, int v)//输出路径 { int now; if(u == v) { Pi(v); return ; } now = path[u][v]; printf("%d-->", u); put_path(now, v); } int main() { while(Si(n)==1 && n) { input(); floyd(); int s, t; while(scanf("%d%d", &s, &t)==2) { if(s==-1 && t==-1) break; printf("From %d to %d :\n", s, t); if(s == t) { printf("Path: %d\n", t); printf("Total cost : %d\n\n", map[s][t]); continue; } printf("Path: "); put_path(s, t); printf("Total cost : %d\n\n", map[s][t]); } } return 0; }