zoukankan      html  css  js  c++  java
  • 最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)

    /*
    考虑到测试数据中需要求解任意两点间的最短路,所以采用Floyd-Warshall算法
     
    dp[i][j] = min(dp[i][k] + dp[k][j] + tax[k], dp[i][j]);
     
    关键在于记录路径,并且要保证:if there are more minimal paths, output the lexically smallest one.
    分两种情况讨论:
    	(1)dp[i][j] > dp[i][k] + dp[k][j] + tax[k]
    		直接更新dp[i][j],保证获得最短路
    	(2)dp[i][j] == dp[i][k] + dp[k][j] + tax[k]
    		看i节点的直接后继节点编号哪个更小,哪个小选哪个,保证获得 the lexically smallest one。
     
    为记录路径:
    	path[i][j] := 在节点i到节点j的最短路径上,i的直接后继节点编号。
    	初始值:path[i][j] = j
    	用这种办法可以记录路径的原因:
    		有n个节点,从1->n的最短路径,假设是这样的1->2->3->4->...->n,则2->n的最短路径
    		必然是2->3->4->...->n,3->n的最短路径必然是3->4->...->n,如果不是这样的,那么
    		当前1->n的路径必然不是1->n的最短路径,与假设矛盾。
    	通过循环即可获得1->n的完整最短路径。
    */
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <cstddef>
      5 #include <iterator>
      6 #include <algorithm>
      7 #include <string>
      8 #include <locale>
      9 #include <cmath>
     10 #include <vector>
     11 #include <cstring>
     12 #include <map>
     13 #include <utility>
     14 #include <queue>
     15 #include <stack>
     16 #include <set>
     17 using namespace std;
     18 const int INF = 0x3f3f3f3f;
     19 const int MaxN = 205;
     20 const int modPrime = 3046721;
     21 
     22 int N;
     23 int dp[MaxN][MaxN];
     24 int tax[MaxN];
     25 int path[MaxN][MaxN];
     26 
     27 
     28 void Solve()
     29 {
     30     for (int i = 0; i < N; ++i)
     31     {
     32         for (int j = 0; j < N; ++j)
     33         {
     34             path[i][j] = j;
     35         }
     36     }
     37     for (int k = 0; k < N; ++k)
     38     {
     39         for (int i = 0; i < N; ++i)
     40         {
     41             for (int j = 0; j < N; ++j)
     42             {
     43                 //dp[i][j] = min(dp[i][k] + dp[k][j] + tax[k], dp[i][j]);
     44                 if (dp[i][j] > dp[i][k] + dp[k][j] + tax[k])
     45                 {
     46                     dp[i][j] = dp[i][k] + dp[k][j] + tax[k];
     47                     path[i][j] = path[i][k];
     48                 }
     49                 else
     50                 {
     51                     if (dp[i][j] == dp[i][k] + dp[k][j] + tax[k])
     52                     {
     53                         if (path[i][j] > path[i][k])
     54                         {
     55                             path[i][j] = path[i][k];
     56                         }
     57                     }
     58                 }
     59             }
     60         }
     61     }
     62 
     63     int src, dsn;
     64     while ((~scanf("%d %d", &src, &dsn)) && !(src == -1 && dsn == -1))
     65     {
     66         printf("From %d to %d :
    ", src, dsn);
     67         printf("Path: "); 
     68         int tmp = src - 1;
     69         printf("%d", src);
     70         while (tmp != dsn - 1)
     71         {
     72             printf("-->");
     73             printf("%d", path[tmp][dsn - 1] + 1);
     74             tmp = path[tmp][dsn - 1];
     75         }
     76         
     77 
     78         printf("
    ");
     79         printf("Total cost : %d
    
    ", dp[src - 1][dsn - 1]);
     80     }
     81 }
     82 
     83 int main()
     84 {
     85 #ifdef HOME
     86     freopen("in", "r", stdin);
     87     //freopen("out", "w", stdout);
     88 #endif
     89 
     90     while (~scanf("%d", &N) && N)
     91     {
     92         for (int i = 0; i < N; ++i)
     93         {
     94             for (int j = 0; j < N; ++j)
     95             {
     96                 scanf("%d", &dp[i][j]);
     97                 if (dp[i][j] == -1)
     98                 {
     99                     dp[i][j] = INF;
    100                 }
    101             }
    102         }
    103         for (int i = 0; i < N; ++i)
    104         {
    105             scanf("%d", &tax[i]);
    106         }
    107         Solve();
    108     }
    109 
    110 
    111 #ifdef HOME
    112     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
    113     _CrtDumpMemoryLeaks();
    114 #endif
    115     return 0;
    116 }
    
    
    
     
  • 相关阅读:
    计算机基础学习路线路线详情:4步骤·5门课
    python课程体系是怎么样的?
    老猿学5G扫盲贴:中国移动5G融合计费漫游计费架构和路由方案
    老猿学5G扫盲贴:中国移动网络侧CHF主要功能及计费处理的主要过程
    moviepy音视频剪辑:moviepy中的剪辑相关类及关系
    老猿学5G扫盲贴:与用户和终端相关的名词UE、SUPI、GPSI、PEI
    PyQt+moviepy音视频剪辑实战文章目录
    PyQt+moviepy音视频剪辑实战2:一个剪裁视频文件精华内容留存工具的实现
    PyQt+moviepy音视频剪辑实战2:实现一个剪裁视频文件精华内容留存工具
    PyQt+moviepy音视频剪辑实战1:多个音视频合成顺序播放或同屏播放的视频文件实现详解
  • 原文地址:https://www.cnblogs.com/shijianming/p/5025609.html
Copyright © 2011-2022 走看看