First, create a bipartite graph (x, y) for the classic parity. For the adjacent two-point edge 2 * (X & Y), source-> X edge, Y-> sink edge, the weight value W is vertex weight, and the minimum cut is obtained.
Consider a path source-> X-> Y-> sink
If the cut edge is source-> X, it indicates that point y is selected, and NO x is selected. The answer is W (x + y)-W (X)
If y-> is selected for the edge Cutting, X points are selected instead of Y points. The answer is W (x + y)-W (y)
If X-> Y is selected for the edge Cutting, Y is selected and X is selected. The answer is W (x + y)-W (2 * (X & Y ))
That is, the sum point right-the smallest cut
# Include <cstdio> # include <cstring> # include <cmath> # include <iostream> # include <algorithm> # include <set> # include <map> # include <queue> # include <vector> # include <string> # define EPS 1e-12 # define INF 0x7fffffff # define maxn 22222 using namespace STD; int n, m, K; int en; int St, Ed; // Source Vertex and sink vertex int dis [maxn]; // dis [I], int que [9999999]; struct edge {int to, C, next ;}; edge e [9999999]; int head [maxn]; void add (int A, int B, int c) {e [En]. to = B; E [En]. C = C; E [En]. next = head [a]; head [a] = EN ++; E [En]. to = A; E [En]. C = 0; E [En]. next = head [B]; head [B] = EN ++;} int BFS () {memset (DIS,-1, sizeof (DIS )); dis [st] = 0; int front = 0, rear = 0; que [rear ++] = sT; while (front <rear) {Int J = que [Front ++]; for (int K = head [J]; k! =-1; k = E [K]. next) {int I = E [K]. to; If (DIS [I] =-1 & E [K]. c) {dis [I] = dis [J] + 1; que [rear ++] = I; if (I = ed) return true ;}}} return false;} int DFS (int x, int MX) {int I, A; If (x = ed) return MX; int ret = 0; for (int K = head [X]; k! =-1 & RET <MX; k = E [K]. next) {If (E [K]. C & dis [E [K]. to] = dis [x] + 1) {int dd = DFS (E [K]. to, min (E [K]. c, Mx-RET); e [K]. c-= dd; E [k ^ 1]. c + = dd; RET + = dd ;}} if (! RET) dis [x] =-1; return ret;} bool vis [100] [100]; void Init () {en = 0; ST = 0; // source ED = N * m + 1; // sink memset (Head,-1, sizeof (head); memset (VIS, 0, sizeof (VIS ));} int DX [] = {100,-100}; int dy [] = {-,}; int A [] []; int ID [100] [100]; int ans; void build () {int x, y, z; ans = 0; For (INT I = 1, CNT = 1; I <= N; I ++) {for (Int J = 1; j <= m; j ++) {scanf ("% d ", & A [I] [J]); ans + = A [I] [J]; Id [I] [J] = CNT ++ ;}} for (INT I = 1; I <= K; I ++) {scanf ("% d % D ", & X, & Y); If (X % 2 = Y % 2) add (St, Id [x] [Y], INF ); else add (ID [x] [Y], Ed, INF); vis [x] [Y] = 1;} For (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= m; j ++) {if (I % 2 = J % 2) {for (int d = 0; D <4; D ++) {int II = I + dx [d]; int JJ = J + dy [d]; if (II> = 1 & II <= N & JJ> = 1 & JJ <= m) {Add (ID [I] [J], id [II] [JJ], 2 * (a [I] [J] & A [II] [JJ]) ;}} if (! Vis [I] [J]) add (St, Id [I] [J], a [I] [J]);} else if (! Vis [I] [J]) add (ID [I] [J], Ed, a [I] [J]) ;}} int dinic () {int TMP = 0; int maxflow = 0; while (BFS () {While (TMP = DFS (St, INF) maxflow + = TMP;} return maxflow ;} int main () {While (scanf ("% d", & N, & M, & K )! = EOF) {Init (); Build (); printf ("% d \ n", ANS-dinic ());}}
HDU 3657 game minimum cut