题目:最短路径
问题描述
求图中任意两个顶点之间的最短路径。
输入格式
输入数据第一行是一个正整数,表示图中的顶点个数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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void Print(int v1, int v2, int path[100][100]);
int main()
{
int n;
int i, j, k;
int arcs[100][100] = { 0 };
int path[100][100];
scanf("%d", &n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arcs[i][j]);
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (arcs[i][j] < 10000)
path[i][j] = i;
else
path[i][j] = -1;
}
}
for (k = 0; k < n; k++)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (arcs[i][j] > arcs[i][k] + arcs[k][j])
{
arcs[i][j] = arcs[i][k] + arcs[k][j];
path[i][j] = path[k][j];
}
}
}
}
while (1)
{
int v1, v2;
scanf("%d %d", &v1, &v2);
if (v1 == -1 && v2 == -1)
break;
if (arcs[v1][v2] == 10000)
{
printf("NO\n");
}
else
{
printf("%d\n", arcs[v1][v2]);
Print(v1, v2, path);
}
}
return 0;
}
void Print(int v1, int v2, int path[100][100])
{
int base[100] = { 0 };
int* top = base;
*top = v2;
top++;
while (path[v1][v2] != v1)
{
v2 = path[v1][v2];
*top = v2;
top++;
}
*top = v1;
top++;
while (top != base)
{
int e = *(top - 1);
top--;
printf("%d ", e);
}
printf("\n");
}