poj1797 Heavy Transportation

题意:

给定无向图,每条边有最大容量。从点1到点n的一条路径的容量取决于这条路径上容量最小的边的容量。现从点1到点n运输,求容量最大的路径的容量。

思路:

1. 令w[i]表示从点1到点i运输的最大流量,则w[i] = max(min(w[j], cost[j][i]), (1 <= j <= n))。可以用类似于最短路的算法来计算,如 (1)spfa (2)dijkstra (3)堆优化的dijkstra等。

2. 最大生成树。即求满足使1~n连通的容量最大的边的容量。

3. 二分 + dfs。

实现:

1.

(1)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <queue>
 5 using namespace std;
 6 
 7 const int MAXN = 1005;
 8 const int INF = 0x3f3f3f3f;
 9 
10 bool in[MAXN];
11 int w[MAXN], T, n, m, x, y, c;
12 int G[MAXN][MAXN];
13 
14 int spfa()
15 {
16     queue<int> q;
17     q.push(1);
18     while (!q.empty())
19     {
20         int tmp = q.front();
21         q.pop();
22         in[tmp] = false;
23         for (int i = 1; i <= n; i++)
24         {
25             if (min(w[tmp], G[tmp][i]) > w[i])
26             {
27                 w[i] = min(w[tmp], G[tmp][i]);
28                 if (!in[i])
29                 {
30                     in[i] = true;
31                     q.push(i);
32                 }
33             }
34         }
35     }
36     return w[n];
37 }
38 int main()
39 {
40     cin >> T;
41     for (int t = 1; t <= T; t++)
42     {
43         cin >> n >> m;
44         for (int i = 1; i <= n; i++)
45         {
46             w[i] = (i == 1 ? INF : 0);
47             in[i] = (i == 1 ? true : false);
48             for (int j = 1; j <= n; j++)
49             {
50                 G[i][j] = 0;
51             }
52         }
53         for (int i = 0; i < m; i++)
54         {
55             scanf("%d %d %d", &x, &y, &c);    
56             G[x][y] = G[y][x] = c;
57         }
58         cout << "Scenario #" << t << ":" << endl;
59         cout << spfa() << endl << endl;
60     }
61     return 0;
62 }

(2)

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 1005;
const int INF = 0x3f3f3f3f;

bool vis[MAXN];
int w[MAXN], T, n, m, x, y, c;
int G[MAXN][MAXN];

int dijkstra()
{
    for (int i = 1; i < n; i++)
    {
        int maxn = 0;
        int index = -1;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && w[j] > maxn)
            {
                maxn = w[j];
                index = j;
            }
        }
        if (index == -1)
            break;
        vis[index] = true;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && min(w[index], G[index][j]) > w[j])
            {
                w[j] = min(w[index], G[index][j]);
            }
        }
    }
    return w[n];
}

int main()
{
    cin >> T;
    for (int t = 1; t <= T; t++)
    {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            w[i] = (i == 1 ? INF : 0);
            vis[i] = false;
            for (int j = 1; j <= n; j++)
            {
                G[i][j] = 0;
            }
        }
        for (int i = 0; i < m; i++)
        {
            scanf("%d %d %d", &x, &y, &c);
            G[x][y] = G[y][x] = c;
        }
        cout << "Scenario #" << t << ":" << endl;
        cout << dijkstra() << endl << endl;
    }
    return 0;
}

(3)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <queue>
 5 using namespace std;
 6 typedef pair<int, int> P;
 7 const int MAXN = 1005;
 8 const int INF = 0x3f3f3f3f;
 9 
10 bool vis[MAXN];
11 int w[MAXN], T, n, m, x, y, c;
12 int G[MAXN][MAXN];
13 
14 int dijkstra_heap()
15 {
16     priority_queue<P> q;
17     q.push(P(INF, 1));
18     while (!q.empty())
19     {
20         P tmp = q.top();
21         q.pop();
22         int now = tmp.second;
23         if (tmp.first < w[now])
24             continue;
25         for (int i = 1; i <= n; i++)
26         {
27             if (min(w[now], G[now][i]) > w[i])
28             {
29                 w[i] = min(w[now], G[now][i]);
30                 q.push(P(w[i], i));
31             }
32         }
33     }
34     return w[n];
35 }
36 int main()
37 {
38     cin >> T;
39     for (int t = 1; t <= T; t++)
40     {
41         cin >> n >> m;
42         for (int i = 1; i <= n; i++)
43         {
44             w[i] = (i == 1 ? INF : 0);
45             vis[i] = false;
46             for (int j = 1; j <= n; j++)
47             {
48                 G[i][j] = 0;
49             }
50         }
51         for (int i = 0; i < m; i++)
52         {
53             scanf("%d %d %d", &x, &y, &c);
54             G[x][y] = G[y][x] = c;
55         }
56         cout << "Scenario #" << t << ":" << endl;
57         cout << dijkstra_heap() << endl << endl;
58     }
59     return 0;
60 }

2.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int MAXN = 1005;
 9 
10 int T, n, m, x, y, c;
11 
12 struct edge
13 {
14     int a, b, cost;
15 };
16 edge es[1000005];
17 int ran[MAXN];
18 int par[MAXN];
19 
20 void init(int n)
21 {
22     for (int i = 0; i < n; i++)
23     {
24         par[i] = i;
25         ran[i] = 0;
26     }
27 }
28 
29 int find(int x)
30 {
31     if (par[x] == x)
32         return x;
33     return par[x] = find(par[x]);
34 }
35 
36 void unite(int x, int y)
37 {
38     x = find(x);
39     y = find(y);
40     if (x == y)
41         return;
42     if (ran[x] < ran[y])
43     {
44         par[x] = y;
45     }
46     else
47     {
48         par[y] = x;
49         if (ran[x] == ran[y])
50         {
51             ran[x] ++;
52         }
53     }
54 }
55 
56 bool same(int x, int y)
57 {
58     return find(x) == find(y);
59 }
60 
61 bool cmp(edge a, edge b)
62 {
63     return a.cost > b.cost;
64 }
65 
66 int kruskal()
67 {
68     init(n);
69     sort(es, es + m, cmp);
70     for (int i = 0; i < m; i++)
71     {
72         if (!same(es[i].a, es[i].b))
73         {
74             unite(es[i].a, es[i].b);
75         }
76         if (same(0, n - 1))
77             return es[i].cost;
78     }
79     return es[m - 1].cost;
80 }
81 
82 int main()
83 {
84     cin >> T;
85     for (int t = 1; t <= T; t++)
86     {
87         cin >> n >> m;
88         for (int i = 0; i < m; i++)
89         {
90             scanf("%d %d %d", &x, &y, &c);
91             es[i].a = x - 1;
92             es[i].b = y - 1;
93             es[i].cost = c;
94         }
95         cout << "Scenario #" << t << ":" << endl;
96         cout << kruskal() << endl << endl;
97     }
98     return 0;
99 }

 3.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int MAXN = 1005;
 8 
 9 bool vis[MAXN];
10 int T, n, m, x, y, c;
11 int G[MAXN][MAXN];
12 
13 bool dfs(int now, int x)
14 {
15     if (now == n)
16         return true;
17     vis[now] = true;
18     for (int i = 1; i <= n; i++)
19     {
20         if (G[now][i] >= x && !vis[i])
21             if (dfs(i, x))
22                 return true;
23     }
24     return false;
25 }
26 
27 bool check(int x)
28 {
29     memset(vis, 0, sizeof(vis));
30     return dfs(1, x);
31 }
32 
33 int search(int maxn)
34 {
35     int l = 1, r = maxn, m, res = 0;
36     while (l <= r)
37     {
38         int m = (l + r) >> 1;
39         if (check(m))
40         {
41             l = m + 1;
42             res = m;
43         }
44         else
45         {
46             r = m - 1;
47         }
48     }
49     return res;
50 }
51 int main()
52 {
53     cin >> T;
54     for (int t = 1; t <= T; t++)
55     {
56         scanf("%d %d", &n, &m);
57         memset(G, 0, sizeof(G));
58         int maxn = 0;
59         for (int i = 0; i < m; i++)
60         {
61             scanf("%d %d %d", &x, &y, &c);
62             G[x][y] = G[y][x] = c;
63             maxn = max(maxn, c);
64         }
65         cout << "Scenario #" << t << ":" << endl;
66         cout << search(maxn) << endl << endl;
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/wangyiming/p/6382985.html