Chessboard
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 19296 | Accepted: 6088 |
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
题意:一个n*m的棋盘,上面有k个洞。现在有2*1的矩形块无限个,需要铺满棋盘,有洞的地方不能铺,其余要铺满,问能不能做到。
思路:一个点可以和它上下左右四个点连边,所以先遍历一遍棋盘,每遍历一个点,把它和它左边和上面不是洞的点连一条无向边,这样就建好了图,跑一次二分匹配,比较最大匹配与不是洞格子数的数量关系,如果是2倍就可以。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define max_v 35*35
int V;
vector<int>G[max_v];
int match[max_v];
bool used[max_v];
void add_edge(int u,int v)
{
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v)
{
used[v]=true;
for(int i=0;i<G[v].size();i++)
{
int u=G[v][i],w=match[u];
if(w<0||!used[w]&&dfs(w))
{
match[v]=u;
match[u]=v;
return true;
}
}
return false;
}
int bipartite_matching()
{
int res=0;
memset(match,-1,sizeof(match));
for(int v=0;v<V;v++)
{
if(match[v]<0)
{
memset(used,0,sizeof(used));
if(dfs(v))
{
res++;
}
}
}
return res;
}
struct node
{
double x;
double y;
}gph[105];
double dis(double x1,double y1,double x2,double y2)
{
return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
}
bool map[35][35];
int main()
{
int n,m,num;
while(~scanf("%d%d%d",&n,&m,&num))
{
for(int i=0;i<max_v;i++)G[i].clear();
V=n*m;
memset(map,0,sizeof(map));
int x,y;
for(int i=0;i<num;i++)
{
scanf("%d%d",&x,&y);
map[y-1][x-1]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j])continue;
if(i-1>=0&&!map[i-1][j])
{
add_edge(i*m+j+1,(i-1)*m+j+1);
}
if(j-1>=0&&!map[i][j-1])
{
add_edge(i*m+j+1,i*m+j);
}
}
}
if(bipartite_matching()*2<n*m-num)
printf("NO\n");
else
printf("YES\n");
}
}