poj 2446 Chessboard (二分匹配)

Chessboard










Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 12800   Accepted: 4000

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.

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

和 hdu 1507类似,构无向图然后判断匹配数是否等于合法的格数。

心算32*32错了= = RE了两次,开始以为32*32是90+,第二次以为是900+,笔算后才知道是1024..


 1 //224K    125MS    C++    1731B    2014-06-10 12:44:41
2 #include<iostream>
3 #include<vector>
4 #define N 1050
5 using namespace std;
6 vector<int>V[N];
7 int match[N];
8 int vis[N];
9 int g[35][35];
10 int dfs(int u)
11 {
12 for(int i=0;i<V[u].size();i++){
13 int v=V[u][i];
14 if(!vis[v]){
15 vis[v]=1;
16 if(match[v]==-1 || dfs(match[v])){
17 match[v]=u;
18 return 1;
19 }
20 }
21 }
22 return 0;
23 }
24 int hungary(int n)
25 {
26 int ret=0;
27 memset(match,-1,sizeof(match));
28 for(int i=1;i<=n;i++){
29 memset(vis,0,sizeof(vis));
30 ret+=dfs(i);
31 }
32 return ret;
33 }
34 int main(void)
35 {
36 int n,m,k,x,y;
37 while(scanf("%d%d%d",&n,&m,&k)!=EOF)
38 {
39 memset(g,0,sizeof(g));
40 for(int i=0;i<N;i++) V[i].clear();
41 for(int i=0;i<k;i++){
42 scanf("%d%d",&y,&x);
43 g[x-1][y]=1;
44 }
45 int map[N]={0},pos=0;
46 for(int i=0;i<n;i++)
47 for(int j=1;j<=m;j++)
48 if(!g[i][j]){
49 if(!map[i*m+j]) map[i*m+j]=++pos;
50 int u=map[i*m+j];
51 if(j<m && !g[i][j+1]){
52 if(!map[i*m+j+1]) map[i*m+j+1]=++pos;
53 V[u].push_back(map[i*m+j+1]);
54 V[map[i*m+j+1]].push_back(u);
55 }
56 if(i<n-1 && !g[i+1][j]){
57 if(!map[(i+1)*m+j]) map[(i+1)*m+j]=++pos;
58 V[u].push_back(map[(i+1)*m+j]);
59 V[map[(i+1)*m+j]].push_back(u);
60 }
61 }
62 //printf("%d\n",pos);
63 if(hungary(pos)==pos) puts("YES");
64 else puts("NO");
65 }
66 return 0;
67 }

时间: 2024-10-07 07:36:55

poj 2446 Chessboard (二分匹配)的相关文章

poj 2446 Chessboard (二分图利用奇偶性匹配)

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13176   Accepted: 4118 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

poj 1469 COURSES (二分匹配)

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16877   Accepted: 6627 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss

POJ 3041 - 最大二分匹配

这道题实现起来还是比较简单的,但是理解起来可能有点困难. 我最开始想到的是贪心法,每次消灭当前小行星最多的一行或一列.然而WA了.Discuss区里已经有高人给出反例. 下面给出正确的解法 我们把行和列抽象成点,把小行星抽象成边,每出现一个小行星,就把其行列所对应的点连起来.这样就形成了一个无向图$G=\left(V, E\right)$.问题就转化为了求这个图G中的最小点覆盖,即求一个元素数量尽可能小的点集$V' \subset V$,$E$中的所有边均与其内的一点相连. 最小点覆盖问题是一个

POJ 2446 Chessboard (二分图最大匹配)

题目链接:http://poj.org/problem?id=2446 给你一个n*m的棋盘,其中有k个洞,现在有1*2大小的纸片,纸片不能覆盖洞,并且每个格子最多只能被覆盖一次.问你除了洞口之外这个棋盘是否能被纸片填满. 这个题目一眼很难看出是二分图匹配... 可以根据i和j性质可以看出,i+j为奇数的上下相邻的i'和j'一定是偶数,那么一个1*2的纸片的i+j一定是一个奇数一个偶数.所以我是建立一个二分图两个集合,将i+j为奇数的点与上下左右相邻的点连在一起,当然点不是洞.最后就用匈牙利算法

poj COURSES(二分匹配)

题目链接:http://poj.org/problem?id=1469 COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17135   Accepted: 6730 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your tas

POJ 2446 Chessboard

要求用占两格的长方形铺满平面上除去指定点 二分图匹配 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int dx[]={1,-1,0,0}; 6 int dy[]={0,0,1,-1}; 7 int map[40][40]; 8 int vis[40][40]; 9 int link[40*40]; 10 int m,n,k; 11 bool

POJ - 2446 Chessboard 二分图 最大匹配(输入坑)

题目大意:有一个n*m的棋盘,棋盘上面有k个洞. 现在要求你在这棋盘上面放1*2的矩形,使得棋盘上除k个洞之外的所有点都被1 * 2的矩形覆盖,且只覆盖一次 解题思路:思路不难想到,将每一点作为两个点集(除洞之外),点集之间的联系表示该点能联通的点,这样二分图就构造完成了 只需要求出最大匹配数,再和n * m -k比较即可 输入是个坑啊,输入的坐标是(x,y),但是表示的缺失y行,x列 #include<cstdio> #include<cstring> #include<v

POJ 2446 Chessboard(二分图最大匹配)

题意: M*N的棋盘,规定其中有K个格子不能放任何东西.(即不能被覆盖) 每一张牌的形状都是1*2,问这个棋盘能否被牌完全覆盖(K个格子除外) 思路: M.N很小,把每一个可以覆盖的格子都离散成一个个点,然后二分图最大匹配. 一个重要的问题**:可不可能存在建完的图是这样的情况:1-2,2-3,3-4,4-5,5-1?这种情况二分图最大匹配是5,但实际上答案是不对的. 证明:不可能存在这样的由奇个点构成的环图.我们按这种方法来看看能不能构造出这样一个棋盘. 假设有2k+1个个格(奇数),则第k+

poj 2226 Muddy Fields(合理建图+二分匹配)

1 /* 2 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 3 思路: 4 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1,然后让我们通过选择一行,或者 5 是一列将其所在行的或者所在列的 1全部删掉,求出最少需要几步? 6 7 这道题的思路就是:将行标 和 列标值为1的建立一条边!通过匈牙利算法可以得到这个二分图的最大匹配数 8 最大匹配数==最小顶点覆盖数!最小顶点覆盖就是用最少的点覆盖了这个二分图