You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
2.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 10010, M = 40010;
int n, m;
int dx[] = {-1, 0, 1, 0}; // 上右下左
int dy[] = {0, 1, 0, -1}; // 上右下左
int g[N]; // 一维的转换后表示如果手欠想写成二维的一定要注意不能写N要写110否则会SE,不要问我是怎么知道的!
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
// 匈牙利算法模板
int match[N], st[N];
int find(int u) {
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (st[v]) continue;
st[v] = 1;
if (match[v] == -1 || find(match[v])) {
match[v] = u;
return 1;
}
}
return 0;
}
int main() {
memset(h, -1, sizeof h); // 初始化链式前向星
memset(match, -1, sizeof match); // 初始化匈牙利算法的匹配标识数组
scanf("%d %d", &n, &m);
while (m--) {
int a, b;
scanf("%d%d", &a, &b);
// 因为要做坐标变换需要下标从0开始本题下标从1开始采用减一大法
a--, b--;
g[a * n + b] = 1;
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (g[i * n + j]) continue; // 出发点有障碍物不可以
if ((i + j) % 2 == 0) continue; // 出发点是黑色点不可以
for (int k = 0; k < 4; k++) {
int tx = i + dx[k], ty = j + dy[k];
if (g[tx * n + ty]) continue; // 目标点有障碍物
if (tx < 0 || tx == n || ty < 0 || ty == n) continue; // 目标点出界
add(i * n + j, tx * n + ty); // 加边
}
}
int res = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if ((i + j) % 2 == 1) {
memset(st, 0, sizeof st);
res += find(i * n + j);
}
printf("%d\n", res);
return 0;
}