题目链接:
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 ", ++cases); 60 printf("%d tons ", 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 ", ++cases); 67 printf("%d tons ", d[v]); 68 } 69 return 0; 70 }