codevs2171 棋盘覆盖
题目描述 Description
给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。
输入描述 Input Description
第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列
输出描述 Output Description
一个数,即最大覆盖格数
样例输入 Sample Input
8 0
样例输出 Sample Output
32
数据范围及提示 Data Size & Hint
经典问题
/* 模板题 */ #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<stack> #define ll long long using namespace std; const int N = 30500; struct edge{ int v; int nxt; }e[N*3]; int head[N],cnt; int n,m; bool vis[205][205]; int chk[N],mch[N]; int read(){ int x=0,f=1; char ch=getchar(); while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}; while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();}; return x*f; } void ins(int u,int v){ cnt++; e[cnt].v = v; e[cnt].nxt = head[u]; head[u] = cnt; } bool dfs(int u){ int to; for(int i = head[u];i;i=e[i].nxt){ to = e[i].v; if(!chk[to]){ chk[to] = true; if(mch[to] == -1 || dfs(mch[to])){ mch[to] = u; mch[u] = to; return true; } } } return false; } void hun(){ int ans = 0,lm = n*n; memset(mch,-1,sizeof(mch)); for(int i = 1;i <= lm;i++){ if(mch[i] == -1){ memset(chk,0,sizeof(chk)); if(dfs(i)) ++ans; } } cout<<ans; } int main(){ n = read(); m = read(); int x,y; for(int i = 1;i <= m;i++){ y = read(); x = read(); vis[y][x] = true; } for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ if(vis[i][j]) continue; if(j < n && !vis[i][j+1]){ ins((i-1)*n+j,(i-1)*n+j+1); ins((i-1)*n+j+1,(i-1)*n+j); } if(i < n && !vis[i+1][j]){ ins((i-1)*n+j,i*n+j); ins(i*n+j,(i-1)*n+j); } } } hun(); return 0; }