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).
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:
A VALID solution.
An invalid solution, because the hole of red color is covered with a card.
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 2 2 1 3 3
Sample Output
YES
Hint
A possible solution for the sample input.
Source
POJ Monthly,charlescpp
题意:m*n的棋盘上,有k个洞,让你用1*2的卡片覆盖整个棋盘,要求洞不能被覆盖,一个格子只能且必须被覆盖到一次,能输出YES,不能输出NO
思路:给每个格子相邻不是洞的格子连边,然后求最大匹配ans,如果ans*2+k==n*m,那么就输出YES,否则输出NO
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define maxn 1600
int n,m,k,id,head[maxn],cnt=0,line[maxn],mp[maxn][maxn],vis[maxn];
struct
{
int to,next;
} edge[maxn*maxn*3];
void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void init()
{
memset(mp,-1,sizeof(mp));
memset(line,-1,sizeof(line));
memset(head,-1,sizeof(head));
cnt=0;
}
int dfs(int u)
{
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].to;
if(vis[v]==0)
{
vis[v]=1;
if(line[v]==-1||dfs(line[v])==1)
{
line[v]=u;
return 1;
}
}
}
return 0;
}
int slove()
{
int ans=0;
for(int i=1; i<=id; i++)
{
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
return ans;
}
int main()
{
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{
init();
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
mp[i][j]=0;
}
for(int i=1; i<=k; i++)
{
int x,y;
scanf("%d %d",&x,&y);
mp[y][x]=1;
}
id=0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
id++;
if(mp[i][j]==0&&mp[i][j+1]==0)
addedge(id,id+1);
if(mp[i][j]==0&&mp[i][j-1]==0)
addedge(id,id-1);
if(mp[i][j]==0&&mp[i-1][j]==0)
addedge(id,id-m);
if(mp[i][j]==0&&mp[i+1][j]==0)
addedge(id,id+m);
}
}
int ans=slove();
if(ans+k==n*m)
printf("YES\n");
else
printf("NO\n");
}
}