最短路径
描述:
求图中任意两个顶点之间的最短路径。
输入:
输入数据第一行是一个正整数,表示图中的顶点个数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;
}