题目:​​http://poj.org/problem?id=2446​


Chessboard


Time Limit: 2000MS

 

Memory Limit: 65536K

Total Submissions: 15250

 

Accepted: 4751


Description


Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2 to cover the board. However, she thinks it too easy to bob, so she makes some holes on the board (as shown in the figure below). 


poj 2446 Chessboard(经典二分匹配)_poj


We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below: 


1. Any normal grid should be covered with exactly one card. 


2. One card should cover exactly 2 normal adjacent grids. 



Some examples are given in the figures below: 



poj 2446 Chessboard(经典二分匹配)_poj_02

 


A VALID solution.



poj 2446 Chessboard(经典二分匹配)_ios_03

 


An invalid solution, because the hole of red color is covered with a card.



poj 2446 Chessboard(经典二分匹配)_ios_04

 


An invalid solution, because there exists a grid, which is not covered.


Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.


Input


There are 3 integers in the first line: m, n, k (0 < m, n <= 32, 0 <= K < m * n), the number of rows, column and holes. In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column.


Output


If the board can be covered, output "YES". Otherwise, output "NO".


Sample Input


4 3 22 1 3 3


Sample Output


YES


Hint



poj 2446 Chessboard(经典二分匹配)_poj_05

 

A possible solution for the sample input.

分析:一眼能看出这是二分匹配吗?所以我觉得这很经典(当然我也是听了别人的思路才懂的)。一张卡片是1*2的规模,所以一个格子就有上下左右四种可能的相邻的格子与他组合成卡片(没有hole),这就是匹配的雏形,于是用邻接表把所有格子的各种匹配情况都表示出来,最后用匈牙利最大匹配求出结果再与总的格子数,holes数做关系比较就能得到最终的判断。


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=2000;
bool bmap[N][N],bmask[N],tag[35][35];
int nx,ny,cx[N],cy[N];
int find(int u){
for(int j=1;j<=ny;j++){
if(bmap[u][j]&&!bmask[j]){
bmask[j]=1;
if(cy[j]==-1||find(cy[j])){
cy[j]=u;
cx[u]=j;
return 1;
}
}
}
return 0;
}
int maxmatch(){
int res=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
for(int i=1;i<=nx;i++){
if(cx[i]==-1){
for(int j=1;j<=ny;j++) bmask[j]=0;
res+=find(i);
}
}
return res;
}
int dir[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
int main()
{
//freopen("cin.txt","r",stdin);
int m,n,k;
while(cin>>m>>n>>k){
int a,b;
nx=ny=n*m;
memset(tag,0,sizeof(tag));
memset(bmap,0,sizeof(bmap));
for(int i=0;i<k;i++){
scanf("%d%d",&b,&a);
tag[a][b]=1;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(tag[i][j]==1) continue;
int x,y;
for(int k=0;k<4;k++){
x=i+dir[k][0];
y=j+dir[k][1];
if(x<=m&&x>=1&&y<=n&&y>=1&&tag[x][y]==0){
a=(i-1)*n+j;
b=(x-1)*n+y;
bmap[a][b]=1;
}
}
}
}
int res=maxmatch();
//cout<<res<<endl;
if(res==m*n-k) puts("YES");
else puts("NO");
}
return 0;
}