POJ 2446 Chessboard (二分图匹配)

题目链接:http://poj.org/problem?id=2446


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). 
POJ 2446 Chessboard (二分图匹配)_第1张图片
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: 
POJ 2446 Chessboard (二分图匹配)_第2张图片 
A VALID solution.
POJ 2446 Chessboard (二分图匹配)_第3张图片 
An invalid solution, because the hole of red color is covered with a card.
POJ 2446 Chessboard (二分图匹配)_第4张图片 
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

POJ 2446 Chessboard (二分图匹配)_第5张图片 
A possible solution for the sample input.

Source

POJ Monthly,charlescpp

PS:

把每个空格子当成一个点。
然后对于每个格子如果可以往上、下、左、右去找可以建立的边。
然后求最大匹配,如果最大匹配数刚好等于空格子数,输出YES,否则NO。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int LN , RN;
#define MAXN 2000
int n,m;
int g[MAXN][MAXN], linker[MAXN];
bool used[MAXN];
int dfs(int L)//从左边开始找增广路径
{
    int R;
    for(R = 0 ; R < RN ; R++ )
    {
        if(g[L][R]!=0 && !used[R])
        {
            //找增广路,反向
            used[R]=true;
            if(linker[R] == -1 || dfs(linker[R]))
            {
                linker[R]=L;
                return 1;
            }
        }
    }
    return 0;//这个不要忘了,经常忘记这句
}
int hungary()
{
    int res = 0 ;
    int L;
    memset(linker,-1,sizeof(linker));
    for( L = 0 ; L < LN ; L++ )
    {
        memset(used,0,sizeof(used));
        if(dfs(L) != 0)
            res++;
    }
    return res;
}
int main()
{
    int k,i,j,res,s,m,n,x,y;
    int num[70][70],graph[70][70];
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        memset(g,0,sizeof(g));
        memset(num,0,sizeof(num));
        for(i = 1 ; i <= k ; i++ )
        {
            scanf("%d%d",&x,&y);
            x--;
            y--;
            graph[y][x] = 1;
        }
        int ans=0;
        for(i = 0 ; i < n ; i++ )
        {
            for(j = 0 ; j < m ; j++ )
            {
                if(graph[i][j]==0)
                    num[i][j]=ans++;
            }
        }
        LN = RN = ans;
        for(i = 0 ; i < n ; i++ )
        {
            for( j = 0 ; j < m ; j++ )
            {

                if(graph[i][j]==0)
                {
                    int u = num[i][j];
                    if(i>0 && graph[i-1][j]==0)
                        g[u][num[i-1][j]]=1;
                    if(j>0 && graph[i][j-1]==0)
                        g[u][num[i][j-1]]=1;
                    if(i < n-1 && graph[i+1][j]==0)
                        g[u][num[i+1][j]]=1;
                    if(j < m-1 && graph[i][j+1]==0)
                        g[u][num[i][j+1]]=1;
                }
            }
        }
        res = hungary();
        if(res == ans)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0 ;
}


你可能感兴趣的:(Algorithm,算法,poj)