zoukankan      html  css  js  c++  java
  • Floyd算法——保存路径——输出路径 HDU1385

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1385

    参考 http://blog.csdn.net/shuangde800/article/details/8075165

    题目大意:

    有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度。

    如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费)。

    现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和。

    求最小花费,如果有多条路经符合,则输出字典序最小的路径。

    解析:

    直接跑一边Floyd算法就好    用一个二维数组保存路径path[ i ][ j ]表示第i个节点到第j个节点经过的第一个点(例如1->2->5->4,path[1][4]=2,path[2][4]=5,path[5][4]=5)

    AC代码

     1 #include <stdio.h>
     2 #include <math.h>
     3 #include <string.h>
     4 #include <stdlib.h>
     5 #include <iostream>
     6 #include <sstream>
     7 #include <algorithm>
     8 #include <string>
     9 #include <queue>
    10 #include <map>
    11 #include <vector>
    12 using namespace std;
    13 const int maxn = 10005;
    14 const int maxm = 1e4+10;
    15 const int inf = 0x3f3f3f3f;
    16 const double epx = 1e-10;
    17 typedef long long ll;
    18 int n;
    19 int w[maxn][maxn];
    20 int path[maxn][maxn];
    21 int tax[maxn];
    22 void init()
    23 {
    24     for(int i=0;i<=n;i++)
    25     {
    26         for(int j=0;j<=n;j++)
    27         {
    28             if(i!=j)
    29                 w[i][j]=inf;
    30             else
    31                 w[i][j]=0;     //自己到自己设为0
    32             path[i][j]=j;    //初始化为j
    33         }
    34     }
    35 }
    36 void Floyd()
    37 {
    38     for(int k=1;k<=n;k++)
    39     for(int i=1;i<=n;i++)
    40     for(int j=1;j<=n;j++)
    41         if(w[i][k]!=inf&&w[k][j]!=inf) 
    42         {
    43             int temp=w[i][k]+w[k][j]+tax[k];    //tax[]是过路费
    44             if(w[i][j]>temp)                   //松弛操作的时候,顺带更新路径
    45             {
    46                 w[i][j]=temp;
    47                 path[i][j]=path[i][k];
    48             }
    49             else if(w[i][j]==temp&&path[i][j]>path[i][k])//字典序最小,不要求字典序的话可直接省略
    50             {
    51                 path[i][j]=path[i][k];
    52             }
    53         }
    54 }
    55 int main()
    56 {
    57     while(cin>>n&&n)
    58     {
    59         init();
    60         for(int i=1;i<=n;i++)
    61         {
    62             for(int j=1;j<=n;j++)
    63             {
    64                 cin>>w[i][j];
    65                 if(w[i][j]==-1)
    66                     w[i][j]=inf;
    67             }
    68         }
    69         for(int i=1;i<=n;i++)
    70             cin>>tax[i];
    71         Floyd();
    72         int s,e;
    73         while(cin>>s>>e&&s!=-1&&e!=-1)
    74         {
    75             printf("From %d to %d :
    ",s,e);
    76             printf("Path: ");
    77             int u=s;
    78             printf("%d",u);                 //打印路径
    79             while(u!=e)          
    80             {
    81                 printf("-->%d",path[u][e]);
    82                 u=path[u][e];
    83             }
    84             printf("
    ");
    85             printf("Total cost : %d
    
    ",w[s][e]);
    86         }
    87 
    88     }
    89 }
  • 相关阅读:
    祝好,又十年
    关于简书的吐槽与思考还有杂七杂八负面情绪宣泄
    康威生命游戏———孤独会致命,拥挤也一样(转载)
    Bran的内核开发教程(bkerndev)-07 中断描述符表(IDT)
    Ubuntu安装QQ
    Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)
    Ubuntu安装scrcpy手机投屏和控制(Ubuntu用QQ微信的另一种方法)
    C、C++的Makefile模板
    C语言打印当前所在函数名、文件名、行号
    Bran的内核开发教程(bkerndev)-05 打印到屏幕
  • 原文地址:https://www.cnblogs.com/stranger-/p/8366904.html
Copyright © 2011-2022 走看看