POJ-2263 Heavy Cargo---最短路變形&&最小邊的最大值
阿新 • • 發佈:2018-04-07
ostream \n memset 就是 現在 兩個 amp 自己的 ret ,三重循環遍歷之後就求出了每兩點之間的最大容量值。註意初始化的時候Map應該都為0,因為求的是最大值
題目鏈接:
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必須取小的值,因為小的值才是這條路的容量值
其實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---最短路變形&&最小邊的最大值