Question: Number of squares in hdoj 1569
Question: No question is asked.
Category: Maximum stream | DP
Analysis: DP should be a number tower model. It is not difficult to do it. Here we will talk about how to convert it into a graph.
The key to this question is to convert it into a bipartite graph to obtain the largest vertex weight independence set of a bipartite graph, while the largest vertex weight independence set = vertex weight and-minimum vertex weight Overwrite
Minimum vertex weight overwrite: select some vertices from X or Y sets so that these vertices overwrite all edges and the weights of the selected vertices are as small as possible.
Maximum vertex weight independent set: Find the weight value and the largest vertex set in the bipartite graph, and then let any vertex have no edge.
Minimum vertex weight overwrite = Minimum Cut = maximum stream = sum-maximum vertex weight Independent Set
For the above knowledge, we want to build a graph now. First, convert the graph into a bipartite graph. We convert the odd number of rows and columns into one side and the even number into one side.
Then, the super Source Vertex s connects one side of the Bipartite Graph and the other side connects to the super sink vertex, And the Edge building capacity between adjacent points is infinite.
AC code:
# Include <cstdio> # include <cstring> # include <iostream> # include <string> # include <algorithm> # include <vector> # include <queue> using namespace STD; # define del (a, B) memset (a, B, sizeof (A) const int n = 3020; const int INF = 0x3f3f3f; int n, m; struct node {int from, to, Cap, flow ;}; vector <int> V [N]; vector <node> E; int vis [N]; // construct the hierarchy chart int cur [N]; void add_node (int from, int to, int cap) {e. push_back (node) {from,, Cap, 0}); E. push_back (node) {to, from, 0, 0}); int TMP = E. size (); V [from]. push_back (tmp-2); V [to]. push_back (tmp-1);} bool BFS (int s, int t) {del (VIS,-1); queue <int> q; q. push (s); vis [s] = 0; while (! Q. empty () {int x = Q. front (); q. pop (); For (INT I = 0; I <V [X]. size (); I ++) {node TMP = E [V [x] [I]; If (vis [TMP. to] <0 & TMP. cap> TMP. flow) // The second condition ensures {vis [TMP. to] = vis [x] + 1; q. push (TMP. to) ;}}} if (vis [T]> 0) return true; return false;} int DFS (int o, int F, int T) {If (O = T | f = 0) // returns F; int A = 0, ANS = 0; For (Int & I = cur [O]; I <V [O]. size (); I ++) // note the preceding '&', which is an important optimization {node & TMP = E [V [O] [I]; if (vis [TMP. to] = (Vis [O] + 1) & (A = DFS (TMP. to, min (F, TMP. cap-tmp.flow), t)> 0) {TMP. flow + = A; E [V [O] [I] ^ 1]. flow-= A; // save graph mode ans + = A; F-= A; If (F = 0) // note break optimization;} return ans; // optimization} int dinci (int s, int t) {int ans = 0; while (BFS (S, T) {del (cur, 0 ); int TM = DFS (S, INF, T); ans + = TM;} return ans;} int MP [60] [60]; int solve (int I, Int J) {return I * m + J;} int main () {// freopen ("input.txt", "r", stdin); While (~ Scanf ("% d", & N, & M) {int sum = 0; For (INT I = 0; I <n; I ++) {for (Int J = 0; j <m; j ++) scanf ("% d", & MP [I] [J]);} // printf ("Yes \ n"); int S = N * m + 1, t = S + 1; for (INT I = 0; I <N; I ++) {for (Int J = 0; j <m; j ++) {sum + = MP [I] [J]; If (I + J) % 2) {add_node (S, solve (I, j), MP [I] [J]); if (I> 0) add_node (solve (I, j ), solve (I-1, J), INF); If (j> 0) add_node (solve (I, j), solve (I, J-1), INF ); if (I <(n-1) add_node (solve (I, j), solve (I + 1, J), INF); If (j <m-1 )) add_node (solve (I, j), solve (I, j + 1), INF);} else add_node (solve (I, j), t, MP [I] [J]) ;}} printf ("% d \ n", Sum-dinci (S, T); For (INT I = 0; I <= T; I ++) V [I]. clear (); E. clear () ;}return 0 ;}
Number of hdoj 1569 squares (largest vertex weight Independent Set-> largest Stream]