最短路径
描述:
求图中任意两个顶点之间的最短路径。
输入:
输入数据第一行是一个正整数,表示图中的顶点个数n(顶点将分别按0,1,…,n-1进行编号)。之后的n行每行都包含n个整数,第i行第j个数表示顶点i-1和顶点j-1之间的边长,用10000来表示两个顶点之间无边。后面每行2个数字,表示一对待求最短路径的顶点,用-1 -1表示输入结束,-1 -1不求解。
输出:
每对待求最短路径的顶点输出两行数据:第一行输出两个顶点间的最短路径长度,第二行输出最短路径,要按顺序输出顶点编号序列,顶点间用空格隔开。当两个顶点间没有路径时,只在一行上输出字符串“NO”。
示例输入
7
0 12 10000 10000 10000 10000 10000
12 0 10000 10000 3 10000 10000
10000 10000 0 10000 10000 21 11
10000 10000 10000 0 10000 10000 10000
10000 3 10000 10000 0 10000 8
10000 10000 21 10000 10000 0 10000
10000 10000 11 10000 8 10000 0
0 2
0 3
5 0
2 1
1 5
-1 -1
示例输出
34
0 1 4 6 2
NO
55
5 2 6 4 1 0
22
2 6 4 1
43
1 4 6 2 5
提示:可以用Floyd算法实现,也可以在Dijkstra算法外面增加一层循环来实现。
#include<stdio.h> #include<stdlib.h> #define INF 100 #define MAXV 100 typedef struct { int edges[MAXV][MAXV]; int n, e; }MatGraph; void Floyd(MatGraph* g, int A[][MAXV], int path[MAXV][MAXV]) { int i, j, k; for (i = 0; i < g->n; i++) { for (j = 0; j < g->n; j++) { A[i][j] = g->edges[i][j]; if ( g->edges[i][j] < INF) path[i][j] = j; else path[i][j] = -1; } } for (k = 0; k < g->n; k++) { for (i = 0; i < g->n; i++) { for (j = 0; j < g->n; j++) { if (A[i][k] + A[k][j] < A[i][j]) { A[i][j] = A[i][k] + A[k][j]; path[i][j] = path[i][k]; } } } } } int main() { int i, j, k; int m, n; int A[MAXV][MAXV]; int path[MAXV][MAXV]; MatGraph* g = (MatGraph*)malloc(sizeof(MatGraph)); scanf("%d", &g->n); for (i = 0; i < g->n; i++) { for (j = 0; j < g->n; j++) scanf("%d", &g->edges[i][j]); } Floyd(g, A, path); for (;;) { scanf("%d %d", &m, &n); if (m == -1 && n == -1) break; k = path[m][n]; if (k < 0) { printf("NO\n"); continue; } printf("%d\n", A[m][n]); printf("%d ", m); while (k != n) { printf("%d ", k); k = path[k][n]; } printf("%d",n); printf("\n"); } return 0; }