您的位置:首页 > 其它

poj1797 Heavy Transportation

2017-02-09 17:09 176 查看
题意:

给定无向图,每条边有最大容量。从点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
;
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
;
}

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
;
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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: