棋盘覆盖
给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。
Input
第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列
Output
一个数,即最大覆盖格数
Sample Input
8 0
Sample Output
32
#include<bits/stdc++.h>
using namespace std;
const int N = 11000;
int g[N], col[N];
int n,m,mat[N];
bool vis[N],er[110][110];
int head[N],now;
struct edges{
int to,next;
}edge[N<<1];
void add(int u,int v){ edge[++now] = {v,head[u]}; head[u] = now;}
int id(int x,int y){
return (x - 1) * n + y;
}
bool dfs(int x){
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(!vis[v]){
vis[v] = 1;
if(!mat[v] || dfs(mat[v])){
mat[v] = x;
return 1;
}
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
int a,b;
for(int i = 1; i <= m; i++){
scanf("%d%d",&a,&b);
er[a][b] = 1;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
if(er[i][j] || (i+j) % 2 == 0)
//如果是故障点或行列之和为偶数就不管了,
//只连那些行列之和为奇数的
continue;
if(j > 1 && !er[i][j-1]) //与左边边
add(id(i,j), id(i,j-1));
if(i > 1 && !er[i-1][j]) //与上方连
add(id(i,j), id(i-1,j));
if(j < n && !er[i][j+1]) //与右边
add(id(i,j), id(i,j+1));
if(i < n && !er[i+1][j]) //与下方
add(id(i,j), id(i+1,j));
}
int ans = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
memset(vis,0,sizeof(vis));
if ((i+j)%2==0)
continue;
if(dfs(id(i,j)))
ans++;
}
// cout<<now<<endl;
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号