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 ",dis[n]); output_ans(pre[n]); printf("%d ",n); return 0; }