This question requires a more detailed understanding of binary matching! At the same time, you need to use a little bit of brains!
Unlike hdu4185, the idea of creating a graph is that 4185 does not need to cover all vertices, but this question requires to cover all vertices and use less oval!
Obviously, a maximum match is required, and then several vertices are not matched. Then, just add several ovans based on the maximum match!
Also, this question was submitted for the first time because I set the maximum number of arrays to 40. I forgot that if each vertex is marked, a total of 400 vertices may exist at most. This is very important! Therefore, you need to know the maximum number of points in the graph you have created for binary matching!
I feel like two-point matching is a postgraduate thinking, and the code is almost the same!
Code:
#include <cstdio>#include <cstring>const int N = 500;int T, n, m, cnt;char g[N][N];int bmap[N][N], cy[N], id[N][N];bool used[N];bool dfs( int u ) { for ( int v = 1; v <= cnt; ++v ) if ( bmap[u][v] && !used[v] ) { used[v] = true; if ( cy[v] == -1 || dfs( cy[v] ) ) { cy[v] = u; return 1; } } return false;}int match(){ int res = 0; memset( cy, -1, sizeof(cy)); for ( int i = 1; i <= cnt; ++i ) { memset( used, 0, sizeof(used)); if ( dfs(i) ) res++; } return res;}int main(){ scanf("%d", &T); while ( T-- ) { scanf("%d%d", &n, &m); getchar(); cnt = 1; for ( int i = 1; i <= n; ++i , getchar()) for ( int j = 1; j <= m; ++j ) { scanf("%c", &g[i][j]); if ( g[i][j] == '*' ) id[i][j] = cnt++; } memset( bmap, 0, sizeof(bmap)); for ( int i = 1; i <= n; ++i ) for ( int j = 1; j <= m; ++j ) { if ( g[i][j] != '*' ) continue; if ( i > 1 && g[i-1][j] == '*' ) bmap[id[i][j]][id[i-1][j]] = 1; if ( j > 1 && g[i][j-1] == '*' ) bmap[id[i][j]][id[i][j-1]] = 1; if ( i < n && g[i+1][j] == '*' ) bmap[id[i][j]][id[i+1][j]] = 1; if ( j < m && g[i][j+1] == '*' ) bmap[id[i][j]][id[i][j+1]] = 1; } cnt--; int tmp = match(); printf("%d\n", cnt - tmp + tmp/2 ); }}