POJ 2446 Chessboard

Chessboard

Time Limit: 2000ms
Memory Limit: 65536KB
This problem will be judged on PKU. Original ID: 2446
64-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.
 

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",n*m - k == 2*ret?"YES":"NO");
46     }
47     return 0;
48 }
View Code

 

posted @ 2015-10-04 09:16  狂徒归来  阅读(233)  评论(0编辑  收藏  举报