题目描述
给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖。

输入格式
第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列 

输出格式
一个数,即最大覆盖格数


#include<bits/stdc++.h>
#define N 105
#define M N*N*2
using namespace std;
int Map[N][N],n,m,ans;
int first[N],next[M],to[M],tot;
int match[M],vis[M];
void add(int x,int y){
next[++tot]=first[x],first[x]=tot,to[tot]=y;
next[++tot]=first[y],first[y]=tot,to[tot]=x;
}
bool find(int x){
for(int i=first[x];i;i=next[i]){
int t=to[i];if(!vis[t]){
vis[t]=1;
if(!match[t] || find(match[t])){
match[t]=x; return true;
}
}
}return false;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y; scanf("%d%d",&x,&y);
Map[x][y]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(Map[i][j]) continue;
if(i+1<=n && !Map[i+1][j]) add((i-1)*n+j , i*n+j);
if(j+1<=n && !Map[i][j+1]) add((i-1)*n+j , (i-1)*n+j+1);
}
}
for(int i=1;i<=n*n;i++){
memset(vis,0,sizeof(vis));
if(find(i)) ans++;
}
printf("%d",ans/2); return 0;
}