/* The minimum vertex coverage and the maximum independent set of the Bipartite Graph can be converted to the maximum matching solution. On this basis, each vertex is assigned a non-negative weight value. The two problems are transformed into: the minimum vertex weight overwrite in the bipartite graph and the maximum vertex weight independence set in the bipartite graph. In a bipartite graph, the minimum vertex weight overwrites some vertices selected from X or Y sets so that these vertices overwrite all edges and the weights of the selected vertex are as small as possible. Modeling: Replace the edges (u, v) in the original Bipartite Graph with the directed edges (u, v) with the capacity INF, and set the Source Vertex S and sink vertex T, connects points in the S and X sets, and the capacity is the weight of the point. connects points in Y with t, and the capacity is the weight of the point. Find the maximum flow in the new graph. the maximum flow is the sum of the weights covered by the minimum point. The largest vertex weight independent set in the bipartite graph finds the weight value and the largest vertex set so that there is no edge between them. In fact, it is a dual problem of least vertex weight coverage. Answer = total weight-least vertex overwrite set. For more information, see hu potao's thesis. Max stream = min cut = min vertex weight overwrite set = sum-Max vertex weight independent set question: an M * n chessboard, each grid has a weight value, and some numbers are extracted from it, so that the lattice where any two numbers are located does not have a public edge, and the obtained number and the maximum value are exclusive. Calculate the maximum value. Solution: The lattice is colored into a bipartite graph, which is obviously the largest vertex weight independence set of the Bipartite Graph. The problem is solved by converting the problem into the weighted least vertex overwrite of the Bipartite Graph. The final result is the total weight and the maximum flow. */# Include <stdio. h> # include <string. h> # define INF 0x7fffffff struct edge // side {int U, V, F, next, B, c; // Number of the edge in the stream available to the front node and the back node of the edge} e [400000]; int head [3000], in [1400], out [1400], M, S, T, SS, TT, Yong, indexx [400000], IND; int N, map [25] [25], sum; void Adde (int from, int to, int Xia, int Shang) // Add edge {// Add edge e [Yong]. U = from, E [Yong]. V = To, E [Yong]. F = Shang-xia, E [Yong]. B = Xia, E [Yong]. C = Shang; E [Yong]. next = head [from], head [F ROM] = Yong ++; // Add its edges at the same time. E [Yong]. U = To, E [Yong]. V = from, E [Yong]. f = 0, E [Yong]. B = Xia, E [Yong]. C = Shang; E [Yong]. next = head [to], head [to] = Yong ++;} int d [3000], num [3000]; int min (int A, int B) {return a <B? A: B;} int sap_gap (int u, int F, int S, int t) // recursive sap {If (u = T) return F; int I, V, mind = T, last = F, cost; for (I = head [u]; I! =-1; I = E [I]. next) {v = E [I]. v; int flow = E [I]. f; If (flow> 0) // when writing a reference template, the flow is written as f {If (d [u] = d [v] + 1) {cost = sap_gap (v, min (last, flow), S, T); e [I]. f-= cost; E [I ^ 1]. F + = cost; last-= cost; If (d [s]> = t + 1) return F-last; If (last = 0) break ;} if (d [v] <mind) Mind = d [v] ;}} if (last = f) {-- num [d [u]; if (Num [d [u] = 0) d [s] = t + 1; d [u] = mind + 1; ++ num [d [u];} return F-last;} int max_f (int s, int t) // call recursive sap {int f = 0; memse T (D, 0, sizeof (d); memset (Num, 0, sizeof (Num); For (Num [s] = t + 1; d [s] <t + 1;) F + = sap_gap (S, INF, S, T); Return F;} int ID (int I, Int J) {return I * m + J;} int main () {int I, j; while (scanf ("% d", & N, & M )! = EOF) {/* n * m points 0 -- N M-1 S = N * n t = S + 1 */SUM = 0; memset (Head,-1, sizeof (head); s = N * m, t = S + 1; for (I = 0; I <n; I ++) {for (j = 0; j <m; j ++) {scanf ("% d", & map [I] [J]); sum + = map [I] [J]; if (I + J) % 2) {Adde (S, ID (I, j), 0, map [I] [J]); if (I> 0) ADDE (ID (I, j), ID (I-1, J), 0, INF); if (I <(n-1) Adde (ID (I, j ), ID (I + 1, J), 0, INF); If (j> 0) Adde (ID (I, j), ID (I, J-1), 0, INF); If (j <m-1) Adde (ID (I, j), ID (I, j + 1), 0, INF );} else {Adde (ID (I, j), T, 0, map [I] [J]) ;}} printf ("% d \ n", sum-max_f (S, t);} return 0 ;}