【9903】最短路径

Time Limit: 10 second
Memory Limit: 2 MB

问题描述
在图中找出从起点到终点的最短路径

Input

Output


Sample Input

7
0 3 5 0 0 0 0
0 0 0 7 8 6 0
0 0 0 0 4 5 0
0 0 0 0 0 0 4
0 0 0 0 0 0 7
0 0 0 0 0 0 6
0 0 0 0 0 0 0

Sample Output

minlong=14
1 2 4 7

Sample Input1

11
0 5 3 0 0 0 0 0 0 0 0
0 0 0 1 6 3 0 0 0 0 0
0 0 0 0 8 0 4 0 0 0 0
0 0 0 0 0 0 0 5 6 0 0
0 0 0 0 0 0 0 5 0 0 0
0 0 0 0 0 0 0 0 0 8 0
0 0 0 0 0 0 0 0 0 3 0
0 0 0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 0 0


Sample Output1

minlong=13
1 3 7 10 11

【题解】

这题考的是最短路径算法,和输出方案。

输出方案的时候在更新解的时候给t记录一下pre[t] = f就可以了。

最后用递归的方法输出。

用的是dijkstra算法,floyd算法来记录方案会很麻烦

【代码】

#include <cstdio>

int n,a[110][110] = {0},w[110][110],pre[110];
bool bo[110];

void output_ans(int x) //用一个递归来输出方案。 
{
	if (x == 0) //递归出口 
		return;
	output_ans(pre[x]);
	printf("%d ",x);
}

int main()
{
	//freopen("F:\\rush.txt","r",stdin);
	scanf("%d",&n);
	for (int i = 1;i <= n;i++)
		for (int j = 1;j <= n;j++)//输入n*n的数组。只要记录一半的数据就可以了。 
			{
				int x;
				scanf("%d",&x);
				if (j > i && x >0)
					{
						a[i][0]++;
						a[i][a[i][0]] = j;
						w[i][j] = x;	
					}
			}
	int dis[110];
	for (int i = 1;i <= n;i++) //一开始起点到所有点的最短距离都为正无穷 
		dis[i] = 2100000000,bo[i] = true;
	dis[1] = 0; //dis[0]置为0 
	for (int i = 1;i <= n;i++)//然后开始进行dijkstra算法 
		{
			int k=-1,min = 2100000000;
			for (int j = 1;j <= n;j++) //找到还没有被涂过的点。 
				if (bo[j] && dis[j] < min)
					{
						k = j;
						min = dis[j];	
					}
			if (k==-1) //如果没找到就结束 
				break;
			bo[k] = false; //这个点标记为被涂过 
			for (int j = 1;j <=a[k][0];j++) //然后从这个点开始 更新与之相连的点 
				if (bo[a[k][j]] && dis[a[k][j]] > dis[k] + w[k][a[k][j]])
					{
						dis[a[k][j]] = dis[k] + w[k][a[k][j]];
						pre[a[k][j]] = k; //并记录其前一个点是什么。 
					}
					
		}
	printf("minlong=%d\n",dis[n]);
	output_ans(pre[n]);
	printf("%d\n",n);
	return 0;	
}


posted @ 2017-10-06 19:23  AWCXV  阅读(127)  评论(0编辑  收藏  举报