1. 程式人生 > >POJ-2263 Heavy Cargo---最短路變形&&最小邊的最大值

POJ-2263 Heavy Cargo---最短路變形&&最小邊的最大值

ostream \n memset 就是 現在 兩個 amp 自己的 ret

題目鏈接:

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 }

POJ-2263 Heavy Cargo---最短路變形&&最小邊的最大值