【题意】:给出n个人,f[i][j]表示他们的友好程度,现在要把这n个人分成两组,使得所有人的开心程度之和最大,既∑∑(-1)1-s[i][j]f[i][j]最大化。其中,s[i][j]表示i和j是否同一组。

【题解】:先假设所有人都在同一组,sum = ∑f[i][j],然后我们需要改变某些人的关系使得n个人分成两组且代价最小,这样问题就转为求一个无向图的全局最小割。
              最后答案为sum - 4 * mincut。

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 
22 #define maxn 100
23 const int inf = 1 << 27;
24 int maz[maxn][maxn];
25 int n, m;
26 
27 int StoerWagner(int n) {//n 为点数
28     int v[maxn], dist[maxn];
29     bool visit[maxn];
30     int cut = inf;
31     for(int i = 0; i < n; i++) v[i] = i;
32     while(n > 1) {
33         int k = 1, pre = 0;
34         for(int i = 1; i < n; i++) {
35             dist[v[i]] = maz[v[0]][v[i]];
36             if(dist[v[i]] > dist[v[k]]) k = i;
37         }
38         memset(visit, falsesizeof(visit));
39         visit[v[0]] = true;
40         for(int i = 1; i < n; i++) {
41             if(i == n - 1) {
42                 cut = min(cut, dist[v[k]]);
43                 for(int j = 0; j < n; j++) {
44                     maz[v[pre]][v[j]] += maz[v[j]][v[k]];
45                     maz[v[j]][v[pre]] += maz[v[j]][v[k]];
46                 }
47                 v[k] = v[--n];
48             }
49             visit[v[k]] = true;
50             pre = k, k = -1;
51             for(int j = 1; j < n; j++) {
52                 if(!visit[v[j]]) {
53                     dist[v[j]] += maz[v[pre]][v[j]];
54                     if(k == -1 || dist[v[k]] < dist[v[j]])
55                         k = j;
56                 }
57             }
58         }
59     }
60     return cut;
61 }
62 
63 int main() {
64     int T;
65     while(scanf("%d", &T), T) {
66         while(T--) {
67             scanf("%d%d", &n, &m);
68             memset(maz, 0, sizeof(maz));
69             int sum = 0;
70             for(int i = 0; i < n; i++)
71                 for(int j = 0; j < n; j++) {
72                     scanf("%d", &maz[i][j]);
73                     sum += maz[i][j];
74                 }
75             int ans = sum - 4 * StoerWagner(n);
76             cout << ans << endl;
77         }
78     }
79     return 0;
80 }
81