#include #include #include #include #include using namespace std; typedef vector VI; typedef vector VVI; // Returns -1 for unmatched items. // Complexity: O(V*E) VI BipartiteMatch(const VVI &mat, VI *back_match = NULL) { int max_item = -1; VI fmat(mat.size(), -1), seen(mat.size(), -1), prev(mat.size()); for (auto row : mat) if (row.size()) max_item = max(max_item, *max_element(row.begin(), row.end())); VI bmat(max_item+1, -1); for (int i = 0; i < mat.size(); i++) { VI q(1, i); seen[i] = i; prev[i] = -1; int x, y; while (!q.empty()) { x = q.back(); q.pop_back(); for (auto it : mat[x]) { int bm = bmat[it]; if (bm == -1) {y = it; goto found_match;} if (seen[bm] < i) { seen[bm] = i; prev[bm] = x; q.push_back(bm); } } } continue; found_match: while (x != -1) { bmat[y] = x; swap(y, fmat[x]); x = prev[x]; } } if (back_match) back_match->swap(bmat); return fmat; } int X, Y; char G[101][101]; int comp[101][101], edge[10001]; bool doit(int x, int y, char ch, int c) { if (x < 0 || x >= X || y < 0 || y >= Y) return false; if (G[y][x] != ch || comp[y][x]) return true; comp[y][x] = c; if (!doit(x+1, y , ch, c)) edge[c] = 1; if (!doit(x-1, y , ch, c)) edge[c] = 1; if (!doit(x , y+1, ch, c)) edge[c] = 1; if (!doit(x , y-1, ch, c)) edge[c] = 1; return true; } int main() { while (cin >> Y >> X) { for (int y = 0; y < Y; y++) cin >> G[y]; memset(comp, 0, sizeof(comp)); memset(edge, 0, sizeof(edge)); int ncomp = 0; for (int y = 0; y < Y; y++) for (int x = 0; x < X; x++) if (!comp[y][x]) { doit(x, y, G[y][x], ++ncomp); } //for (int y = 0; y < Y; y++) { //for (int x = 0; x < X; x++) cout << ' ' << comp[y][x]; //cout << endl; //} VVI match(ncomp+1); for (int x = 0; x < X; x++) for (int y = 0; y < Y; y++) if (!edge[comp[y][x]]) for (int x2 = x-1; x2 <= x+1; x2++) if (x2 >= 0 && x2 < X) for (int y2 = y-1; y2 <= y+1; y2++) if (y2 >= 0 && y2 < Y && abs(x2-x) + abs(y2-y) == 1) { if (edge[comp[y2][x2]] || comp[y][x] == comp[y2][x2]) continue; if (G[y][x] == '1') match[comp[y ][x ]].push_back(comp[y2][x2]); if (G[y][x] == '0') match[comp[y2][x2]].push_back(comp[y ][x ]); } int ret = 0; for (int c = 1; c <= ncomp; c++) { if (edge[c]) { ret++; continue; } VI& v = match[c]; sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); } VI v = BipartiteMatch(match); for (auto x : v) ret += (x != -1); cout << ret << endl; } }