ZOJ-1456 Minimum Transport Cost---Floyd变形+路径输出字典序最小

题目链接:

https://vjudge.net/problem/ZOJ-1456

题目大意:

Spring国家有N个城市,每队城市之间也许有运输路线,也可能没有。现在有一些货物要从一个城市运到另一个城市。运输费有两部分组成:
城市之间的运输成本,路过一个城市的税,除了起点和终点城市。多条路要求字典序最小

思路:

此处运用Floyd的思想,由于每经过一个城市需要交纳费用,所以在加入城市k的时候判断d[i][j]和d[i][k]+d[k][j]+w[k]的大小,此处需要防止i和j等于k的情况。字典序最小存路径就不能按照原来的方法倒叙存储路径,此处的path[i][j]存储的是点i到达点j的最短路径上点i后面的点。初始化的时候如果点a和点b之间存在路径,那么path[a][b] = b,每次加入中间点k时,如果可以更新最短路,path[i][j]应该等于path[i][k],因为存的是i到j的最短路径上i点后面的那个点的值,如果k点加入可以更新最短路,那么从i到j的路径上i点后面的点应该变成从i到k的路径上i点后面的点的值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 using namespace std;
12 typedef long long ll;
13 const int maxn = 1e2 + 10;
14 const int INF = 1e9 + 7;
15 int T, n, m, cases;
16 int Map[maxn][maxn];
17 int path[maxn][maxn];//path[i][j]存从i点出发到j带你的路径上,i点的后一个点
18 int w[maxn];
19 int main()
20 {
21     while(cin >> n && n)
22     {
23         memset(path, -1, sizeof(path));
24         for(int i = 1; i <= n; i++)
25         {
26             for(int j = 1; j <= n; j++)
27             {
28                 cin >> Map[i][j];
29                 if(Map[i][j] < 0)Map[i][j] = INF;
30                 else if(i != j)path[i][j] = j;
31             }
32         }
33         for(int i = 1; i <= n; i++)
34         {
35             cin >> w[i];
36         }
37         for(int k = 1; k <= n; k++)
38         {
39             for(int i = 1; i <= n; i++)
40             {
41                 for(int j = 1; j <= n; j++)
42                 {
43                     if(i == k || j == k)continue;
44                     if(Map[i][j] > Map[i][k] + w[k] + Map[k][j])
45                     {
46                         Map[i][j] = Map[i][k] + Map[k][j] + w[k];
47                         path[i][j] = path[i][k];
48                     }
49                     else if(Map[i][j] == Map[i][k] + Map[k][j] + w[k] && path[i][j] != -1 && path[i][k] != -1)
50                     {
51                         path[i][j] = min(path[i][j], path[i][k]);
52                     }
53                 }
54             }
55         }
56         int u, v;
57         while(cin >> u >> v && (u + v > 0))
58         {
59             printf("From %d to %d :\n", u, v);
60             int x = u;
61             printf("Path: %d", x);
62             while(x != v)
63             {
64                 printf("-->%d", path[x][v]);
65                 x = path[x][v];
66             }
67             puts("");
68             printf("Total cost : %d\n\n", Map[u][v]);
69         }
70     }
71     return 0;
72 }

 

posted @ 2018-04-08 15:30  _努力努力再努力x  阅读(182)  评论(0编辑  收藏  举报