棋盘覆盖

给出一张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;
}

  

  

原文地址:https://www.cnblogs.com/cutemush/p/12738800.html