POJ-2263 Heavy Cargo---最短路变形&&最小边的最大值

题目链接:

https://vjudge.net/problem/POJ-2263

题目大意:

有n个城市,m条连接两个城市的道路,每条道路有自己的最大复载量。现在问从城市a到城市b,车上的最大载重能为多少。

思路:

这里求的不是最短路,求的是最大容量路,意思就是每条路的最小边就是这条路的容量值,要求出最大的容量值。可以用Floyd的思想来求解。设Map[i][j]表示从i到j的容量值,递推方程变成:

Map[i][j] = MAX{ Map[i][j],  MIN{ Map[i][k],  Map[k][j] } 。这里需要好好的思考一下,对于点i和点j,中间点的加入更改的递推式应该取最大值,因为求的就是最大的容量值,而对于新加进来的i-k和k-j必须取小的值,因为小的值才是这条路的容量值,三重循环遍历之后就求出了每两点之间的最大容量值。注意初始化的时候Map应该都为0,因为求的是最大值

其实Dijkstra和Bellman算法也可以求解,同样的松弛方程改成上述含义就可以。

拓展:POJ2253 最大边的最小值,思路一样,方程正好相反

Floyd:

 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 #define MEM(a, b) memset(a, b, sizeof(a));
12 using namespace std;
13 typedef long long ll;
14 const int maxn = 200 + 10;
15 const int INF = 0x3f3f3f3f;
16 int T, n, m, cases, tot;
17 int Map[maxn][maxn];
18 map<string, int>id;
19 set<string>cnt;
20 int getid(string s)
21 {
22     if(cnt.count(s))return id[s];
23     cnt.insert(s);
24     return id[s] = cnt.size();
25 }
26 int main()
27 {
28     while(cin >> n >> m && (n + m))
29     {
30         string s1, s2;
31         int d;
32         cnt.clear();
33         id.clear();
34         for(int i = 0; i <= n; i++)
35         {
36             for(int j = 0; j <= n; j++)Map[i][j] = 0;
37         }
38         for(int i = 0; i < m; i++)
39         {
40             cin >> s1 >> s2 >> d;
41             int u = getid(s1);
42             int v = getid(s2);
43             //cout<<u<<" "<<v<<endl;
44             Map[v][u] = Map[u][v] = d;
45         }
46         cin >> s1 >> s2;
47         for(int k = 1; k <= n; k++)
48         {
49             for(int i = 1; i <= n; i++)
50             {
51                 for(int j = 1; j <= n; j++)
52                 {
53                     Map[i][j] = max(Map[i][j], min(Map[i][k], Map[j][k]));
54                 }
55             }
56         }
57         int u = getid(s1);
58         int v = getid(s2);
59         printf("Scenario #%d\n", ++cases);
60         printf("%d tons\n\n", Map[u][v]);
61     }
62     return 0;
63 }

dijkstra:

 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 #define MEM(a, b) memset(a, b, sizeof(a));
12 using namespace std;
13 typedef long long ll;
14 const int maxn = 200 + 10;
15 const int INF = 0x3f3f3f3f;
16 int T, n, m, cases, tot;
17 int Map[maxn][maxn];
18 map<string, int>id;
19 set<string>cnt;
20 int d[maxn];
21 bool v[maxn];
22 void dijkstra(int u)
23 {
24     MEM(v, 0);
25     MEM(d, 0);
26     d[u] = INF;
27     for(int i = 0; i < n; i++)
28     {
29         int x, m = 0;//求距离最远的加入
30         for(int i = 1; i <= n; i++)if(!v[i] && d[i] >= m)m = d[x = i];//找到最大的标记
31         v[x] = 1;
32         //cout<<m<<endl;
33         for(int i = 1; i <= n; i++)d[i] = max(d[i], min(d[x], Map[x][i]));
34     }
35 }
36 int getid(string s)
37 {
38     if(cnt.count(s))return id[s];
39     cnt.insert(s);
40     return id[s] = cnt.size();
41 }
42 int main()
43 {
44     while(cin >> n >> m && (n + m))
45     {
46         string s1, s2;
47         int w;
48         cnt.clear();
49         id.clear();
50         for(int i = 0; i <= n; i++)
51         {
52             for(int j = 0; j <= n; j++)Map[i][j] = 0;
53         }
54         for(int i = 0; i < m; i++)
55         {
56             cin >> s1 >> s2 >> w;
57             int u = getid(s1);
58             int v = getid(s2);
59             //cout<<u<<" "<<v<<endl;
60             Map[v][u] = Map[u][v] = w;
61         }
62         cin >> s1 >> s2;
63         int u = getid(s1);
64         int v = getid(s2);
65         dijkstra(u);
66         printf("Scenario #%d\n", ++cases);
67         printf("%d tons\n\n", d[v]);
68     }
69     return 0;
70 }

 

posted @ 2018-04-07 14:09  _努力努力再努力x  阅读(480)  评论(0编辑  收藏  举报