Min. cut ... The two-point staining then turns the color of the dots to the Yuanhui of the opposite. And then you can do it.
A point (x, y):
S->id (x, y) (return), id (x, y)->t (cost), ID (i,j) &&id (neighboring node)->newid (I,j) (+oo), NewId (i,j)->t (return)
Then dye the different dots in turn.
The initial answer is 2*∑ return, so that each point will either cut 1 returns, or Cut 2 returns, or cut the 1 return + price. All correspond to each of the options
--------------------------------------------------------------------------------
#include <cstdio>#include <cstring>#include <algorithm>#include <cctype>using namespace std;#define ID (x, y) ((x) * M + (y))#define CHK (x, y) (0 <= (x) && (x) < N && 0 <= (y) && (y) < M)const int MAXN = 5009;const int INF = 1 <<;const int Dx[4] = {-1, 0, 0, 1};const int Dy[4] = {0, 1,-1, 0}; inline int Read () {char C = getchar ();int ret = 0;For (;!isdigit (c); c = GetChar ());For (; IsDigit (c); c = GetChar ()) ret = RET * + C-' 0 ';return ret;} struct Edge {int to, cap;Edge *next, *rev;} e[5000000], *pt = E, *HEAD[MAXN], *P[MAXN], *CUR[MAXN];inline void Add (int u, int v, int w) {pt->to = v;pt->cap = w;pt->next = Head[u];Head[u] = pt++;}inline void Addedge (int u, int v, int w) {Add (U, V, W);Add (V, u, 0);Head[u]->rev = head[v];Head[v]->rev = Head[u];}int N, M, S, T, V, ans;int H[MAXN], CNT[MAXN];void Solve () {for (int i = 0; i < V; i++) cur[i] = Head[i];memset (CNT, 0, sizeof CNT);memset (h, 0, sizeof h);cnt[0] = V;edge* E;int Flow = 0;for (int x = S, A = INF; H[s] < V;) {For (e = cur[x]; e; e = e->next)if (e->cap && h[e->to] + 1 = = H[x]) break;if (e) {a = min (A, e->cap);cur[x] = p[e->to] = e;if ((x = e->to) = = = T) {For (; x! = S; x = p[x]->rev->to) {P[x]->cap-= A;P[x]->rev->cap + = A;}Flow + = A;A = INF;}} else {if (!--Cnt[h[x]]) break;h[x] = V;For (e = head[x]; e; e = e->next) if (E->cap && h[e->to] + 1 < h[x]) {h[x] = h[e->to] + 1;cur[x] = e;}cnt[h[x]]++;if (x! = S)x = p[x]->rev->to;}}printf ("%d\n", (ans << 1)-Flow);} void Init () {N = read (); M = Read ();V = N * M; S = v++; T = v++;for (int i = 0; i < N; i++)For (int j = 0; J < M; J + +)(i + j) & 1? Addedge (ID (i, j), T, Read ()): Addedge (S, id (i, j), read ());ans = 0;for (int i = 0; i < N; i++)For (int j = 0; J < M; J + +) {int v = read (), NP = v++;ans + = v;if ((i + j) & 1) {Addedge (S, Id (i, J), V);Addedge (NP, T, v);Addedge (Id (i, J), NP, INF);for (int k = 0; k < 4; k++) {int x = i + dx[k], y = j + dy[k];if (chk (x, y))Addedge (Id (x, y), NP, INF);}} else {Addedge (Id (i, J), T, v);Addedge (S, NP, V);Addedge (NP, Id (i, J), INF);for (int k = 0; k < 4; k++) {int x = i + dx[k], y = j + dy[k];if (chk (x, y))Addedge (NP, Id (x, y), INF);}}}}int main () {Init ();Solve ();return 0;}
--------------------------------------------------------------------------------
3774: Best Choice Time Limit:1 Sec Memory Limit:MB
Submit:96 Solved:48
[Submit] [Status] [Discuss] Description
The small n Hand has a n*m chart, control a point to pay the price of AIJ, then a point if it is controlled, or all the points around him (up and down) are controlled, then he is considered to be selected. A point if selected, then you can get bij return, now please help small n Choose an optimal scheme, so that the return-the cost as large as possible.
Input
The first line, two positive integer n,m, indicates the length and width of the grid chart.
The next n rows of m integers per line AIJ represent the cost of control.
The next n rows of m integers per line bij indicate the return of the selection.
Output
An integer that represents the maximum return-price (if one does not control then it is 0).
Sample Input 3 3
1 100 100
100 1 100
1 100 100
2 0 0
5 2 0
2 0 0Sample Output 8HINT
for 100% of data, n,m<=50 , Aij,bij are less than or equal to - a positive integer.
Source
Bzoj 3774: Optimal selection (min cut)