Loading

POJ 2914:Minimum Cut(全局最小割Stoer-Wagner算法)

http://poj.org/problem?id=2914

题意:给出n个点m条边,可能有重边,问全局的最小割是多少。

思路:一开始以为用最大流算法跑一下,然后就超时了。后来学习了一下这个算法,是个模板题。具体学习可以参考:

http://blog.sina.com.cn/s/blog_700906660100v7vb.html

http://www.cnblogs.com/ylfdrib/archive/2010/08/17/1801784.html

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 #define INF 0x3f3f3f3f
 6 #define N 505
 7 int mp[N][N], vis[N], wage[N], combine[N], S, T, ans, mincut, m, n;
 8 
 9 void search() {
10     memset(vis, 0, sizeof(vis));
11     memset(wage, 0, sizeof(wage));
12     S = T = -1;
13     int ma, index;
14     for(int i = 0; i < n; i++) {
15         ma = -INF;
16         for(int j = 0; j < n; j++) {
17             if(!vis[j] && !combine[j] && wage[j] > ma) {
18                 ma = wage[j]; index = j;
19             }
20         }
21         if(T == index) return ;
22         vis[index] = 1;
23         S = T; T = index;
24         mincut = ma;
25         for(int j = 0; j < n; j++) {
26             if(!vis[j] && !combine[j]) wage[j] += mp[T][j];
27         }
28     }
29 }
30 
31 int Stoer_Wagner() {
32     ans = INF;
33     memset(combine, 0, sizeof(combine));
34     for(int i = 0; i < n - 1; i++) {
35         search();
36         combine[T] = 1;
37         if(ans > mincut) ans = mincut;
38         for(int j = 0; j < n; j++) {
39             mp[S][j] += mp[T][j];
40             mp[j][S] += mp[j][T];
41         }
42     }
43     return ans;
44 }
45 
46 int main() {
47     while(~scanf("%d%d", &n, &m)) {
48         memset(mp, 0, sizeof(mp));
49         for(int i = 1; i <= m; i++) {
50             int u, v, w;
51             scanf("%d%d%d", &u, &v, &w);
52             mp[u][v] += w;
53             mp[v][u] += w;
54         }
55         printf("%d\n", Stoer_Wagner());
56     }
57     return 0;
58 }

 

posted @ 2017-01-27 00:35  Shadowdsp  阅读(271)  评论(0编辑  收藏  举报