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 ", Stoer_Wagner()); 56 } 57 return 0; 58 }