码迷,mamicode.com
首页 > 其他好文 > 详细

最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)

时间:2015-12-07 12:21:33      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

/*
考虑到测试数据中需要求解任意两点间的最短路,所以采用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 :\n", 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("\n");
 79         printf("Total cost : %d\n\n", 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 }

 

 

最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)

标签:

原文地址:http://www.cnblogs.com/shijianming/p/5025609.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!