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.
[Cpp]
# 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;
}
Else
Map1 [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]);
}
}
// Obtain the maximum matching value.
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;
}