给出一张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 ",ans); return 0; }