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).
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.
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.
这题太坑,坐标输进来是列,行的,开始没注意错了很久,其他没什么难的,只要相邻且不是洞就连边。
然后求最大匹配,如果最大匹配等于剩余格子数量,就是YES,否则是NO
#include<stdio.h>
#include<string.h>
const int maxn=1605;
struct node
{
int to;
int next;
}edge[4*maxn];
int head[maxn];
int mark[maxn];
bool used[maxn];
bool mat[55][55];
int cnt[55][55];
int tot;
int n,m;
int index;
void addedge(int from,int to)
{
edge[tot].to=to;
edge[tot].next=head[from];
head[from]=tot++;
}
bool dfs(int x)
{
for (int i=head[x];i!=-1;i=edge[i].next)
{
if (!used[edge[i].to])
{
used[edge[i].to]=1;
if (mark[edge[i].to]==-1 || dfs(mark[edge[i].to]))
{
mark[edge[i].to]=x;
return true;
}
}
}
return false;
}
int hungary()
{
memset(mark,-1,sizeof(mark));
int ans=0;
for (int i=0;i<index;i++)
{
memset(used,0,sizeof(used));
if (dfs(i))
ans++;
}
return ans;
}
int main()
{
int k;
while (~scanf("%d%d%d",&n,&m,&k))
{
memset(head,-1,sizeof(head));
memset(mat,false,sizeof(mat));
tot=0;
int x,y;
for (int i=0;i<k;i++)
{
scanf("%d%d",&x,&y);
x--;
y--;
mat[y][x]=true;
}
index=0;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (!mat[i][j])
cnt[i][j]=index++;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
{
if (!mat[i][j])
{
if (i>0 && !mat[i-1][j])
addedge(cnt[i][j],cnt[i-1][j]);
if (i<n-1 && !mat[i+1][j])
addedge(cnt[i][j],cnt[i+1][j]);
if (j>0 && !mat[i][j-1])
addedge(cnt[i][j],cnt[i][j-1]);
if (j<m-1 && !mat[i][j+1])
addedge(cnt[i][j],cnt[i][j+1]);
}
}
int res=hungary();
if (res==index)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}