Title: hdoj 5093 battle ships
Here is a n * m chart with the iceberg '#', float o ', and general hai' *'. Now we need to place as many shells as possible in the sea, shells cannot attack each other. How many shells can I know?
Analysis: the Key to the classic question of a bipartite graph is how to create a graph. The graph is numbered twice, numbered by row, and each line can contain the same number of attacked parts, each column is the same, and then edge is connected to the column where the row and column are numbered to find the maximum match at a time. I use the maximum stream to find the maximum match.
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 = 1020; const int INF = 0x3f3f3f; int n, m; int min (int A, int B) {return A> B? B: A ;}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) {node tmp1, tmp2; tmp1.cap = from, tmp1.to =, tmp1.cap = CAP, tmp1.flow = 0; E. push_back (tmp1); tmp2.from = To, tmp2.to = from, tmp2.cap = 0, tmp2.flow = 0; E. push_back (tmp2); 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;} void clear (int x) {for (INT I = 0; I <= x; I ++) V [I]. clear (); E. clear ();} int row [55] [55], Cal [55] [55]; char MP [55] [55]; bool OK [55*55*2]; int main () {// freopen ("input.txt", "r", stdin); int t; scanf ("% d ", & T); While (t --) {int n, m; scanf ("% d", & N, & M); For (INT I = 0; I <n; I ++) {getchar (); For (Int J = 0; j <m; j ++) scanf ("% C ", & MP [I] [J]);} int S = 0, T = 1; int CNT = 2; memset (OK, false, sizeof (OK )); memset (row,-1, sizeof (ROW); memset (CAL,-1, sizeof (CAL); For (INT I = 0; I <N; I ++) // number the row {for (Int J = 0; j <m; j ++) {If (MP [I] [J] = '*') {row [I] [J] = CNT; OK [CNT] = true ;} else if (MP [I] [J] = '#') {If (OK [CNT] = true) CNT ++ ;}} if (OK [CNT] = true) CNT ++;} For (INT I = 2; I <CNT; I ++) add_node (S, I, 1 ); int PS = CNT; For (Int J = 0; j <m; j ++) {for (INT I = 0; I <n; I ++) {If (MP [I] [J] = '*') {Cal [I] [J] = CNT; OK [CNT] = true ;} else if (MP [I] [J] = '#') {If (OK [CNT] = true) CNT ++ ;}} if (OK [CNT] = true) CNT ++;} For (INT I = Ps; I <CNT; I ++) add_node (I, T, 1 ); for (INT I = 0; I <n; I ++) {for (Int J = 0; j <m; j ++) {If (row [I] [J]> 0 & Cal [I] [J]> 0) {add_node (row [I] [J], cal [I] [J], 1) ;}} int ans = dinci (S, T); printf ("% d \ n", ANS ); clear (CNT) ;}return 0 ;}
Hdoj 5093 battle ships [maximum matching of bipartite graphs]