学习粗:https://blog.csdn.net/ddelphine/article/details/77935670
模板题:http://poj.org/problem?id=2914
#include <iostream> #include<cstring> using namespace std; const int maxn=505; int mat[maxn][maxn]; int res; inline int min(int a,int b){if(a<b)return a; return b;} void Mincut(int n) { int node[maxn], dist[maxn]; bool visit[maxn]; int i, prev, j, k; for (i = 0; i < n; i++) node[i] = i; while (n > 1) { int maxj = 1; for (i = 1; i < n; i++) { //初始化到已圈集合的割大小 dist[node[i]] = mat[node[0]][node[i]]; if (dist[node[i]] > dist[node[maxj]]) maxj = i; } prev = 0; memset(visit, false, sizeof (visit)); visit[node[0]] = true; for (i = 1; i < n; i++) { if (i == n - 1) { //只剩最后一个没加入集合的点,更新最小割 res = min(res, dist[node[maxj]]); for (k = 0; k < n; k++) //合并最后一个点以及推出它的集合中的点 mat[node[k]][node[prev]] = (mat[node[prev]][node[k]] += mat[node[k]][node[maxj]]); node[maxj] = node[--n]; //缩点后的图 continue; } visit[node[maxj]] = true; prev = maxj; maxj = -1; for (j = 1; j < n; j++) if (!visit[node[j]]) { //将上次求的maxj加入集合,合并与它相邻的边到割集 dist[node[j]] += mat[node[prev]][node[j]]; if (maxj == -1 || dist[node[maxj]] < dist[node[j]]) maxj = j; } } } return; } int main() { int n, m, a, b, v; while (scanf("%d%d", &n, &m) != EOF) { res = (1 << 29); memset(mat, 0, sizeof (mat)); while (m--) { scanf("%d%d%d", &a, &b, &v); mat[a][b] += v; mat[b][a] += v; } Mincut(n); printf("%d ", res); } return 0; }