棋盤覆蓋[最大匹配]
阿新 • • 發佈:2018-11-24
題目描述
給出一張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; }