bzoj 3175 [Tjoi2013]攻击装置
先黑白染色 再二分图最大独立集
#include<bits/stdc++.h> using namespace std; const int MAXN = 40050; const int MAXM = 1000005; const int INF = 1000000050; int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1, S, T; inline void addedge(int u, int v, int cap) { to[++ed] = v; nxt[ed] = Head[u]; Head[u] = ed; f[ed] = cap; to[++ed] = u; nxt[ed] = Head[v]; Head[v] = ed; f[ed] = 0; return; } inline bool BFS() { int u; memset(lev, -1, sizeof(lev)); queue<int>q; lev[S] = 0; q.push(S); while (q.size()) { u = q.front(); q.pop(); for (int i = Head[u]; i; i = nxt[i]) if (f[i] && lev[to[i]] == -1) { lev[to[i]] = lev[u] + 1; q.push(to[i]); /* if (to[i] == T) { return 1; } magic one way optimize */ } } memcpy(cur, Head, sizeof Head); return lev[T] != -1; } inline int DFS(int u, int maxf) { if (u == T || !maxf) { return maxf; } int cnt = 0; for (int &i = cur[u], tem; i; i = nxt[i]) if (f[i] && lev[to[i]] == lev[u] + 1) { tem = DFS(to[i], min(maxf, f[i])); maxf -= tem; f[i] -= tem; f[i ^ 1] += tem; cnt += tem; if (!maxf) { break; } } if (!cnt) { lev[u] = -1; } return cnt; } int Dinic() { int ans = 0; while (BFS()) { ans += DFS(S, 2147483647); } return ans; } void init(int SS, int TT) { memset(Head, 0, sizeof(Head)); ed = 1; S = SS; T = TT; return; } char ff[205][205]; pair<int, int> xy[400005]; int aim[205][205]; int cnt = 0; const int dir[4][2] {{2, 1}, { -2, 1}, { -1, 2}, {1, 2}}; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%s", ff[i] + 1); } S = 0, T = 40001; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (ff[i][j] == '0') { xy[++cnt] = make_pair(i, j); aim[i][j] = cnt; if ((i + j) & 1) { addedge(cnt, T, 1); } else { addedge(S, cnt, 1); } } } } //cout<<cnt<<endl; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (ff[i][j] == '0') for (int k = 0; k <= 3; k++) { int dx, dy; dx = i + dir[k][0]; dy = j + dir[k][1]; if (dx >= 1 && dx <= n && dy >= 1 && dy <= n) { if (ff[dx][dy] == '0') { if ((i + j) & 1) { addedge(aim[dx][dy], aim[i][j], 1); } else { addedge(aim[i][j], aim[dx][dy], 1); } } } } } } int ans = cnt - Dinic(); cout << ans << endl; return 0; }