(机考)最短路径

…衆ロ難τιáo~ 提交于 2019-12-05 05:36:48

最短路径

描述:

求图中任意两个顶点之间的最短路径。

输入:

       输入数据第一行是一个正整数,表示图中的顶点个数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;

}

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!