Convert to the maximum match.
Each horizontal 'O' and '#' block (must contain 'O') serves as a vertex of the X set, each vertical 'O' and '#' blocks (must contain 'O') serve as a vertex of the Y set.
When 'O' at the intersection of the horizontal block and the vertical block, the two vertices in the bipartite graph are connected by edges.
This question was entered incorrectly because of the subscript. It took a long time for the subscripts to be called.
# Include <iostream> # include <cstring> using namespace STD; const int n = 55; const int max = N * n; struct hori_block {int row; int col_left, col_right ;}; struct ver_block {int Col; int row_up, row_dow ;}; hori_block X [Max]; ver_block y [Max]; char map [N] [N]; bool maze [Max] [Max]; int match [Max]; bool isvisit [Max]; int row, Col; int cnt_x, cnt_y; void build_graph () {cnt_x = 0; cnt_y = 0; For (INT I = 0; I <row; I ++) for (in T j = 0; j <Col; j ++) {If (Map [I] [J] = 'O') {x [cnt_x]. row = I; for (int K = J; k> = 0; k --) if (Map [I] [k]! = '#') X [cnt_x]. col_left = K; elsebreak; while (j <Col & map [I] [J]! = '#') {X [cnt_x]. col_right = J; j ++;} cnt_x ++; }}for (Int J = 0; j <Col; j ++) for (INT I = 0; I <row; I ++) {If (Map [I] [J] = 'O') {Y [cnt_y]. col = J; For (int K = I; k> = 0; k --) if (Map [k] [J]! = '#') Y [cnt_y]. row_up = K; elsebreak; while (I <row & map [I] [J]! = '#') {Y [cnt_y]. row_dow = I; I ++;} cnt_y ++;} memset (maze, false, sizeof (maze); For (INT I = 0; I <cnt_x; I ++) for (Int J = 0; j <cnt_y; j ++) if (X [I]. row> = Y [J]. row_up & X [I]. row <= Y [J]. row_dow & Y [J]. col> = x [I]. col_left & Y [J]. col <= x [I]. col_right & map [x [I]. row] [Y [J]. col] = 'O') maze [I] [J] = true;} bool find (int u) {for (INT I = 0; I <cnt_y; I ++) {If (maze [u] [I] &! Isvisit [I]) {isvisit [I] = true; If (Match [I] =-1 | find (Match [I]) {match [I] = u; return true ;}} return false ;}int max_match () {int ans = 0; memset (match,-1, sizeof (MATCH); For (INT I = 0; I <cnt_x; I ++) {memset (isvisit, false, sizeof (isvisit )); if (find (I) ans ++;} return ans;} int main () {INT cases; CIN> cases; for (int K = 1; k <= cases; k ++) {CIN> row> Col; For (INT I = 0; I <row; I ++) for (Int J = 0; j <Col; j ++) CIN> map [I] [J]; build_graph (); cout <"case:" <k <Endl; cout <max_match () <Endl;} return 0 ;}