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 }
    
    
    
     
  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/shijianming/p/5025609.html
Copyright © 2011-2022 走看看