标签:dep push ++ set code memset 覆盖 表示 else
有一个 $m$ 行 $n$ 列的方格图,每个方格中都有一个正整数。现要从方格中取数,使任意两个数所在方格没有公共边,且取出的数的总和最大,请求出最大的和。
第一行是两个用空格隔开的整数,分别代表方格图的行数 $m$ 和列数 $n$。
第 $2$ 到第 $(m + 1)$$(m + 1)$ 行,每行 $n$ 个整数,第 $(i + 1)$$(i + 1)$ 行的第 $j$个整数代表方格图第 $i$ 行第 $j$ 列的的方格中的数字 $a{i,j}$ 。
输出一行一个整数,代表和最大是多少。
前置:
二分图最大点权独立集:选取一些点使得任意两点间没有边相连
二分图最小点权覆盖集:选取一些点使得任意一条边的两个端点至少有一个被选中
大点权独立集 == 所有点权和 - 最小点权覆盖集
为什么最大点权独立集 == 所有点权和 - 最小点权覆盖集 == 所有点权和 - 最小割呢?
一、"最大点权独立集 == 所有点权和 - 最小点权覆盖集" :
二、"所有点权和 - 最小点权覆盖集 == 所有点权和 - 最小割" :
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define INF 2e9 #define p(i, j) (i - 1) * M + j using namespace std; const int _ = 10005; int N, M, S, T, Ans; struct Edge { int nxt, dis, to; }e[1000005]; int cnte = 1, head[_]; inline void add_Edge(int i, int j, int k) { e[++cnte].dis = k, e[cnte].nxt = head[i], e[cnte].to = j, head[i] = cnte; e[++cnte].dis = 0, e[cnte].nxt = head[j], e[cnte].to = i, head[j] = cnte; } int dep[_]; bool bfs() { queue <int> q; memset(dep, 0, sizeof(dep)); dep[S] = 1, q.push(S); while(!q.empty()) { int u = q.front(); q.pop(); for(int v, i = head[u]; i; i = e[i].nxt) { if(e[i].dis && !dep[v = e[i].to]) { dep[v] = dep[u] + 1, q.push(v); } } } return dep[T]; } int dfs(int u, int in) { if(u == T) return in; int out = 0; for(int v, i = head[u]; i && in; i = e[i].nxt) { if(e[i].dis && dep[v = e[i].to] == dep[u] + 1) { int tmp = dfs(v, min(in, e[i].dis)); e[i].dis -= tmp, e[i ^ 1].dis += tmp, in -= tmp, out += tmp; } } if(!out) dep[u] = 0; return out; } int main() { cin >> N >> M; S = N * M + 1, T = N * M + 2; for(int i = 1; i <= N; ++i) { for(int x, j = 1; j <= M; ++j) { cin >> x, Ans += x; if((i + j) & 1) { add_Edge(S, p(i, j), x); if(i > 1) add_Edge(p(i, j), p(i - 1, j), INF); if(i < N) add_Edge(p(i, j), p(i + 1, j), INF); if(j > 1) add_Edge(p(i, j), p(i, j - 1), INF); if(j < M) add_Edge(p(i, j), p(i, j + 1), INF); } else add_Edge(p(i, j), T, x); } } while(bfs()) Ans -= dfs(S, INF); cout << Ans << ‘\n‘; return 0; }
标签:dep push ++ set code memset 覆盖 表示 else
原文地址:https://www.cnblogs.com/blog-fgy/p/12320743.html