问题模型: 二分图点权最大独立集
转化模型:最小割
建图
和 方格取数问题 建图一样,就是要考虑一下障碍不能被连,或者连到 T
即可。
S - Xi
与 Yi - T
的边容量为 1
。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, inf = 0x7fffffff;
struct Edge {
int next, to, c;
}e[N << 1];
int n, m, tim = 0, s, t;
int a[205][205], number[205][205];
int x[8] = {-2, -1, -2, -1, 2, 1, 2, 1}, y[8] = {-1, -2, 1, 2, -1, -2, 1, 2};
int cnt = 1;
int head[N], cur[N];
void add(int u, int v, int c) {
e[++ cnt].to = v; e[cnt].c = c; e[cnt].next = head[u]; head[u] = cnt;
e[++ cnt].to = u; e[cnt].c = 0; e[cnt].next = head[v]; head[v] = cnt;
}
int dep[N];
bool bfs(int x) {
queue<int> q;
memset(dep, 0, sizeof(dep));
dep[x] = 1; q.push(x);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].to;
if (!dep[v] && e[i].c) { dep[v] = dep[u] + 1; q.push(v); }
}
}
if (!dep[t]) return 0;
return 1;
}
int dfs(int u, int flow) {
if (u == t) return flow;
for (int &i = cur[u]; i; i = e[i].next) {
int v = e[i].to;
if (dep[v] == dep[u] + 1 && e[i].c) {
int nowflow = dfs(v, min(flow, e[i].c));
if (nowflow > 0) {
e[i].c -= nowflow;
e[i ^ 1].c += nowflow;
return nowflow;
}
}
}
return 0;
}
int Dinic() {
int res = 0;
while (bfs(s)) {
for (int i = s; i <= t; i ++) cur[i] = head[i];
while (int d = dfs(s, inf)) res += d;
}
return res;
}
void color() {
for (int i = 0; i < n; i ++)
for (int j = i & 1; j < n; j += 2) {
if (a[i][j] != 1) add(s, number[i][j], 1);
for (int k = 0; k < 8; k ++) {
int xx = i + x[k], yy = j + y[k];
if (xx >= 0 && xx < n && yy >= 0 && yy < n && a[xx][yy] != 1) add(number[i][j], number[xx][yy], inf);
}
}
for (int i = 0; i < n; i ++)
for (int j = i & 1 ^ 1; j < n; j += 2)
if (a[i][j] != 1) add(number[i][j], t, 1);
}
int main() {
memset(a, 0, sizeof(a));
scanf("%d%d", &n, &m);
int sum = n * n - m;
s = 0, t = n * n + 1;
for (int i = 1; i <= m; i ++) {
int aa, bb;
scanf("%d%d", &aa, &bb), a[aa - 1][bb - 1] = 1;
}
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
number[i][j] = ++ tim;
color();
int ans = sum - Dinic();
printf("%d\n", ans);
return 0;
}