Chessboard
Time Limit: 2000ms
Memory Limit: 65536KB
This problem will be judged on PKU. Original ID: 244664-bit integer IO format: %lld Java class name: Main
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.
Source
解题:最大匹配
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 33*33; 7 bool mp[maxn][maxn],used[maxn],cant[50][50]; 8 int Link[maxn],n,m,k; 9 bool match(int u){ 10 for(int i = 0; i < maxn; ++i){ 11 if(!mp[u][i] || used[i]) continue; 12 used[i] = true; 13 if(Link[i] == -1 || match(Link[i])){ 14 Link[i] = u; 15 return true; 16 } 17 } 18 return false; 19 } 20 int main(){ 21 int x,y; 22 while(~scanf("%d%d%d",&n,&m,&k)){ 23 memset(cant,false,sizeof cant); 24 for(int i = 0; i < k; ++i){ 25 scanf("%d%d",&y,&x); 26 cant[x-1][y-1] = true; 27 } 28 memset(mp,false,sizeof mp); 29 for(int i = 0; i < n; ++i){ 30 for(int j = 0; j < m; ++j){ 31 if(((i+j)&1) && !cant[i][j]){ 32 if(i > 0 && !cant[i-1][j]) mp[i*m + j][(i-1)*m + j] = true; 33 if(j > 0 && !cant[i][j-1]) mp[i*m + j][i*m + j - 1] = true; 34 if(i + 1 < n && !cant[i+1][j]) mp[i*m + j][(i+1)*m + j] = true; 35 if(j + 1 < m && !cant[i][j+1]) mp[i*m + j][i*m + j + 1] = true; 36 } 37 } 38 } 39 int ret = 0; 40 memset(Link,-1,sizeof Link); 41 for(int i = 0; i <= m*n; ++i){ 42 memset(used,false,sizeof used); 43 if(match(i)) ++ret; 44 } 45 printf("%s ",n*m - k == 2*ret?"YES":"NO"); 46 } 47 return 0; 48 }