Black and white coloring and then finding the maximum matching of the Bipartite Graph [cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace std;
Const int maxn = 40 + 9;
Int n, m;
Char a [maxn] [maxn];
Struct
{
Int to, next;
} E [maxn * 10*4];
Int head [maxn * 10], lon;
Void edgeini ()
{
Memset (head,-1, sizeof (head ));
Lon =-1;
}
Void edgemake (int from, int)
{
E [++ lon]. to =;
E [lon]. next = head [from];
Head [from] = lon;
}
Int mat [maxn * 10], vist [maxn * 10];
Bool work (int u)
{
// Cout <u <endl;
Vist [u] = 1;
For (int k = head [u]; k! =-1; k = e [k]. next)
{
Int v = e [k].;
If (mat [v] =-1)
{
Mat [v] = u;
Return true;
}
}
For (int k = head [u]; k! =-1; k = e [k]. next)
{
Int v = e [k].;
If (vist [mat [v]) continue;
If (work (mat [v])
{
Mat [v] = u;
Return true;
}
}
Return false;
}
Int solve ()
{
Int ret = 0;
For (int I = 1; I <= n; I ++)
For (int j = 1; j <= m; j ++)
{
If (I + j) % 2 = 0)
{
Memset (vist, 0, sizeof (vist ));
Ret + = work (I * m-m + j );
}
// Cout <I * m-m + j <endl;
}
Return (ret );
}
Int main ()
{
// Freopen ("in.txt", "r", stdin );
Int tcase;
Scanf ("% d", & tcase );
While (tcase --)
{
Edgeini ();
Memset (mat,-1, sizeof (mat ));
Memset (a, 0, sizeof ());
Int ans = 0;
Scanf ("% d", & n, & m );
For (int I = 1; I <= n; I ++)
Scanf ("% s", & a [I] [1]);
For (int I = 1; I <= n; I ++)
For (int j = 1; j <= m; j ++)
If (a [I] [j] = '*')
{
Ans ++;
If (a [I + 1] [j] = '*')
Edgemake (I * m-m + j, I * m + j );
If (a [I-1] [j] = '*')
Edgemake (I * m-m + j, I * m-m + j );
If (a [I] [j + 1] = '*')
Edgemake (I * m-m + j, I * m-m + j + 1 );
If (a [I] [J-1] = '*')
Edgemake (I * m-m + j, I * m-m + J-1 );
}
Int ret = solve ();
Printf ("% d \ n", ans-ret );
}
Return 0;
}