stoer-Wagner算法
进行n轮操作,每轮操作确定一对点s,t被割开情况下的最小割,然后将s,t合并。s,t为操作中最后剩下的两个点。
操作类似prim求最大生成树,每次将与当前集合相邻的距离最大的点合并到集合中,最后剩下s,t两点。
代码来自wiki,可以堆优化
const int maxn = 550; const int inf = 1000000000; int n, r; int edge[maxn][maxn], dist[maxn]; bool vis[maxn], bin[maxn]; void init() { memset(edge, 0, sizeof(edge)); memset(bin, false, sizeof(bin)); } int contract( int &s, int &t ) { // Find s,t memset(dist, 0, sizeof(dist)); memset(vis, false, sizeof(vis)); int i, j, k, mincut, maxc; for(i = 1; i <= n; i++) { k = -1; maxc = -1; for(j = 1; j <= n; j++)if(!bin[j] && !vis[j] && dist[j] > maxc) { k = j; maxc = dist[j]; } if(k == -1)return mincut; s = t; t = k; mincut = maxc; vis[k] = true; for(j = 1; j <= n; j++)if(!bin[j] && !vis[j]) dist[j] += edge[k][j]; } return mincut; } int Stoer_Wagner() { int mincut, i, j, s, t, ans; for(mincut = inf, i = 1; i < n; i++) { ans = contract( s, t ); bin[t] = true; if(mincut > ans)mincut = ans; if(mincut == 0)return 0; for(j = 1; j <= n; j++)if(!bin[j]) edge[s][j] = (edge[j][s] += edge[j][t]); } return mincut; }