1 const int MAX_N = 1;
2 int G[MAX_N][MAX_N];
3 int v[MAX_N]; // v[i]代表节点i合并到的顶点
4 int w[MAX_N]; // 定义w(A,x) = ∑w(v[i],x),v[i]∈A
5 bool visited[MAX_N]; // 用来标记是否该点加入了A集合
6
7 int stoer_wagner(int n)
8 {
9 int min_cut = inf;
10 for (int i = 0; i < n; ++i)
11 {
12 v[i] = i; // 初始还未合并,都代表节点本身
13 }
14
15 while (n > 1)
16 {
17 int pre = 0; // pre用来表示之前加入A集合的点(在t之前一个加进去的点)
18 memset(visited, 0, sizeof(visited));
19 memset(w, 0, sizeof(w));
20 for (int i = 1; i < n; ++i)
21 {
22 int k = -1;
23 for (int j = 1; j < n; ++j) // 选取V-A中的w(A,x)最大的点x加入集合
24 {
25 if (!visited[v[j]])
26 {
27 w[v[j]] += G[v[pre]][v[j]];
28 if (k == -1 || w[v[k]] < w[v[j]])
29 {
30 k = j;
31 }
32 }
33 }
34
35 visited[v[k]] = true; // 标记该点x已经加入A集合
36 if (i == n - 1) // 若|A|=|V|(所有点都加入了A),结束
37 {
38 const int s = v[pre], t = v[k]; // 令倒数第二个加入A的点(v[pre])为s,最后一个加入A的点(v[k])为t
39 min_cut = min(min_cut, w[t]); // 则s-t最小割为w(A,t),用其更新min_cut
40 for (int j = 0; j < n; ++j) // Contract(s, t)
41 {
42 G[s][v[j]] += G[v[j]][t];
43 G[v[j]][s] += G[v[j]][t];
44 }
45 v[k] = v[--n]; // 删除最后一个点(即删除t,也即将t合并到s)
46 }
47 // else 继续
48 pre = k;
49 }
50 }
51 return min_cut;
52 }