O(n^3)的StoerWagner算法
论文:http://wenku.baidu.com/view/072209d5360cba1aa811da51
重要思想:
设s,t ∈ V(G),G'为G合并点s,t后形成的新图,则G的最小割是 min(G的s-t最小割,G'的最小割)。
每次G的一组s-t最小割,然后合并s,t后进行迭代,直到图中只剩一个点,所有s-t最小割中最小的即为G的全局最小割。
Lemma 3.1 证明了MINIMUMCUTPHASE 确实找到了G的一组s-t最小割。
http://poj.org/problem?id=2914
非负权无向图,裸的求全局最小割。
http://acm.hdu.edu.cn/showproblem.php?pid=3691
非负权无向图,给定s,求以s为起点以任意点为终点的最小割。求全局最小割C = (S, T),不妨设s∈S,则C为以s为起点以任意t∈T为终点的一个割,又因为C为全局最小割,所以C即为所求。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <utility>
#include <queue>
#include <climits>
using namespace std;
const int MAXN(301);
const int MAXE(5000010);
const int MAXK(100010);
const int MAXC(2);
const int INF((INT_MAX-1)/2);
const int BASE(20);
const double LIM(1e50);
const double EPS(1e-5);
const double PER(0.02);
const double MUL(3.5);
template<typename T>
inline bool checkmax(T &a, const T &b){
return b > a ? ((a = b), true) : false;
}
template<typename T>
inline bool checkmin(T &a, const T &b){
return b < a ? ((a = b), true) : false;
}
template<typename T>
inline T ABS(T a){
return a < 0 ? -a : a;
}
bool vis[MAXN];
int v[MAXN], w[MAXN], g[MAXN][MAXN];
int Search(int n, int &s, int &t){
for(int i = 0; i < n; ++i){
vis[i] = false;
w[i] = 0;
}
for(int i = 1; i < n; ++i){
int mw = -1, u;
for(int j = 0; j < n; ++j)
if(!vis[j] && checkmax(mw, w[j]))
u = j;
vis[u] = true;
s = u;
for(int k = 0; k < n; ++k)
if(!vis[k])
w[k] += g[v[u]][v[k]];
}
for(int i = 0; i < n; ++i)
if(!vis[i]){
t = i;
return w[i];
}
}
int StoerWagner(int n){
int ret = INF;
for(int i = 0; i < n; ++i) v[i] = i;
while(n > 1){
int s, t;
checkmin(ret, Search(n, s, t));
for(int i = 0; i < n; ++i)
if(i != s && i != t){
g[v[s]][v[i]] += g[v[t]][v[i]];
g[v[i]][v[s]] += g[v[i]][v[t]];
}
for(int j = t+1; j < n; ++j) v[j-1] = v[j];
--n;
}
return ret;
}
int main(){
int n, m, s;
while(scanf("%d%d%d", &n, &m, &s), n){
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
g[i][j] = false;
int u, v, w;
for(int i = 0; i < m; ++i){
scanf("%d%d%d", &u, &v, &w);
--u;
--v;
g[u][v] += w;
g[v][u] += w;
}
printf("%d\n", StoerWagner(n));
}
return 0;
}