• 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
    ", ++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 }
  • 相关阅读:
    jQuery获取鼠标事件源
    windows中MongoDB安装和环境搭建
    前端获取后台数据的方法:ajax、axios、fetch
    浅谈:easy-mock的使用
    安全篇-AES/RSA加密机制
    PHP开发api接口安全验证
    Ajax简单实现文件异步上传的多种方法
    PHP7有没有你们说的那么牛逼
    基于laravel框架构建最小内容管理系统
    redis用法分析
  • 原文地址:https://www.cnblogs.com/fzl194/p/8733161.html
Copyright © 2020-2023  润新知