1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include <iostream> #include <algorithm> #include <cstdio> #include <cstring>
using namespace std;
const int N = 50; const int M = 410;
struct node { int nex, to; };
int T, h, w, n, m, b[N][N]; int used[M], nex[M], head[M], cnt; node edge[M * M]; char s[N][N];
void add_edge(int u, int v) { edge[++cnt].to = v; edge[cnt].nex = head[u]; head[u] = cnt; }
bool find(int u) { for (int i = head[u]; 0 != i; i = edge[i].nex) { int v = edge[i].to; if (used[v]) continue; used[v] = 1; if (0 == nex[v] || find(nex[v])) { nex[v] = u; return true; } } return false; }
int match() { int res = 0; for (int i = 1; i <= n; i++) { memset(used, 0, sizeof(used)); if (find(i)) res++; } return res; }
void init() { cnt = 0; memset(nex, 0, sizeof(nex)); memset(head, 0, sizeof(head)); memset(b, 0, sizeof(b)); }
int main() { scanf("%d", &T); while (T--) { init(); scanf("%d%d", &h, &w); for (int i = 1; i <= h; i++) scanf("%s", s[i] + 1); n = m = 0; for (int i = 1; i <= h; i++) { for (int k = 1; k <= w; k++) { if ('*' != s[i][k]) continue; if (0 == (i + k) % 2) b[i][k] = ++n; else b[i][k] = ++m; } } for (int i = 1; i <= h; i++) { for (int k = 1; k <= w; k++) { if ('*' != s[i][k] || 0 != (i + k) % 2) continue; if (b[i - 1][k]) add_edge(b[i][k], n + b[i - 1][k]); if (b[i + 1][k]) add_edge(b[i][k], n + b[i + 1][k]); if (b[i][k + 1]) add_edge(b[i][k], n + b[i][k + 1]); if (b[i][k - 1]) add_edge(b[i][k], n + b[i][k - 1]); } } int res = match(); printf("%d\n", n + m - res); } return 0; }
|