zoukankan      html  css  js  c++  java
  • 【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
    ",dis[n]);
    	output_ans(pre[n]);
    	printf("%d
    ",n);
    	return 0;	
    }


  • 相关阅读:
    查找表类算法//字母异位词分组
    查找表类算法//四数相加 II
    查找表类算法//四数相加 II
    第六章 类文件结构
    第六章 类文件结构
    查找表的算法//四数之和
    查找表的算法//四数之和
    第五章 调优案例分析与实战
    第五章 调优案例分析与实战
    C++_基础4-分支语句和逻辑运算符
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632361.html
Copyright © 2011-2022 走看看