This is a classic binary match. After the grid is marked as black and white, the grid containing '*' is then divided into two groups based on black and white to create edges. The final result is the total number of '*'-the number of matches.
# Include <iostream> # include <cstdio> # include <vector> using namespace STD; vector <int> map [400]; // create a bipartite graph based on parity: int t, n, m; int match [400], FY [400], LN, RN; int map1 [41] [11]; // original graph int dirt [4] [2] = {, 0,-, 0,-}; int path (int u) {for (INT I = 0, J; I <map [u]. size (); I ++) {J = map [u] [I]; If (! FY [J]) {FY [J] = 1; if (Match [J] =-1 | path (Match [J]) {match [J] = u; return 1 ;}} return 0 ;}int main () {int I, j, X, Y, ans; char TMP; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); Ln = rn = 0; for (I = 1; I <= N; I ++) {getchar (); For (j = 1; j <= m; j ++) {scanf ("% C", & TMP); If (TMP = '*') {If (I + J) & 1) // singularity map1 [I] [J] = ++ ln; else // even point map1 [I] [J] = ++ rn ;} elsemap1 [I] [J] = 0 ;}for (I = 1; I <= ln; I ++) map [I]. clear (); for (I = 1; I <= rn; I ++) Match [I] =-1; // create a bipartite graph for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) {If (! Map1 [I] [J] |! (I + J) & 1) continue; For (int K = 0; k <4; k ++) {x = I + dirt [k] [0]; y = J + dirt [k] [1]; If (x <= 0 | x> N | Y <= 0 | Y> M |! Map1 [x] [Y]) continue; Map [map1 [I] [J]. push_back (map1 [x] [Y]) ;}// calculate the maximum matching ans = 0; for (I = 1; I <= ln; I ++) {for (j = 1; j <= rn; j ++) FY [J] = 0; If (path (I) ans ++ ;} printf ("% d \ n", LN + rn-ans);} return 0 ;}