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

Chessboard

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 14157   Accepted: 4401

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

题意:m*n的矩阵(m是列,n是行),有k个点有洞,问2*1的木板是否可以将剩下的铺满,如果可以,输出yes,否则输出no。

思路:将有洞的格子标记,然后将剩下的格子链接相邻的。差点超时。看到网上有人用奇偶分。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
const int inf=0x3f3f3f3f;
int map[2010][2010];
int G[2010][2010];
int vis[2010];
int link[2010];
int n,m;
int cnt;
int jx[]={1,-1,0,0};
int jy[]={0,0,1,-1};
int dfs(int u)
{
    int i;
    for(i=1; i<=cnt; i++) {
        if(!vis[i]&&map[u][i]) {
            vis[i]=1;
            if(link[i]==-1||dfs(link[i])) {
                link[i]=u;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int k,i,j,l;
    int a,b;
    while(~scanf("%d %d %d",&m,&n,&k)) {
        memset(map,0,sizeof(map));
        memset(link,-1,sizeof(link));
        memset(G,0,sizeof(G));
        cnt=0;
        for(i=1; i<=k; i++) {
            scanf("%d %d",&b,&a);
            G[a][b]=-1;
        }
        for(i=1;i<=m;i++) {
            for(j=1;j<=n;j++) {
                if(!G[i][j])
                    G[i][j]=++cnt;
            }
        }
        for(i=1; i<=m; i++) {
            for(j=1; j<=n; j++) {
                if(G[i][j]!=-1)
                    for(l=0;l<4;l++) {
                        int x=i+jx[l];
                        int y=j+jy[l];
                        if(x>=1&&x<=m&&y>=1&&y<=n) {
                            map[G[i][j]][G[x][y]]=1;
                        }
                    }
            }
        }
        int sum=0;
        for(i=1; i<=cnt; i++) {
            memset(vis,0,sizeof(vis));
            if(dfs(i))
                sum++;
        }
        if(sum==cnt)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
时间: 2024-10-22 04:47:34

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 2239-Selecting Courses(二分图_最大匹配+哈希建图)

Selecting Courses Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8781   Accepted: 3922 Description It is well known that it is not easy to select courses in the college, for there is usually conflict among the time of the courses. Li Mi

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 - 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 1274-The Perfect Stall(二分图_最大匹配)

The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19272   Accepted: 8737 Description Farmer John completed his new barn just last week, complete with all the latest milking technology. Unfortunately, due to engineering pr

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

POJ 3041 Asteroids 二分图之最大匹配

题意:在一个网格中有若干个点,每一次可以清除一行或者一列,问最少几次可以将网格中的点全部清除. 思路:这个题是一个入门的最大匹配题(这个好像不是思路..).一般的方式就是将 行 看作集合A,列 看作集合B. 这么说有点抽象.举个例子:2行3列的矩阵可以看作是集合A={1,2}与B={1,2,3},假设矩阵[1][2] 存在点(别忘了题意),则A中的元素1与B中元素2连有一条边. 这样就可以将题给矩阵转化为二分图,再利用匈牙利算法得到最大匹配数就是答案了. 1 #include<iostream>

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