POJ2446:Chessboard(二分匹配) java程序员

Chessboard
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 10746   Accepted: 3340

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
MYCode:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 1050
struct edge
{
    int v;
    int next;
}E[5000];
int head[MAX];
int pre[MAX];
bool used[MAX];
bool map[35][35];
int n;
int m;
int num;
void init()
{
    memset(head,-1,sizeof(head));
    memset(pre,-1,sizeof(pre));
    memset(map,0,sizeof(map));
    num=0;
}
void add(int s,int t)
{
    E[num].v=t;
    E[num].next=head[s];
    head[s]=num++;
}
bool dfs(int cur)
{
    int i;
    for(i=head[cur];i!=-1;i=E[i].next)
    {
        int v=E[i].v;
        if(!used[v])
        {
            used[v]=1;
            if(pre[v]==-1||dfs(pre[v]))
            {
                pre[v]=cur;
                return true;
            }
        }
    }
    return false;
}
int hungary()
{
    int i;
    int res=0;
    for(i=1;i<=n*m;i++)
    {
        memset(used,0,sizeof(used));
        if(dfs(i))
        res++;
    }
    return res;
}
int main()
{
    int k;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        init();
        int i,j;
        int x,y;
        for(i=1;i<=k;i++)
        {
            scanf("%d%d",&x,&y);
            map[y][x]=1;
        }
        if((n*m-k)%2)
        {
            printf("NO\n");
            continue;
        }
        int id1,id2;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(!map[i][j])
                {
                    id1=(i-1)*m+j;
                    if(j>1&&!map[i][j-1])
                    {
                        id2=id1-1;
                        add(id1,id2);
                    }
                    if(j<m&&!map[i][j+1])
                    {
                        id2=id1+1;
                        add(id1,id2);
                    }
                    if(i>1&&!map[i-1][j])
                    {
                        id2=id1-m;
                        add(id1,id2);
                    }
                    if(i<n&&!map[i+1][j])
                    {
                        id2=id1+m;
                        add(id1,id2);
                    }
                }
            }
        }
        int res=hungary()/2;
        //cout<<"res="<<res<<endl;
        if(res!=(n*m-k)/2)
        {
            printf("NO\n");
        }
        else
        printf("YES\n");
    }
}

//16MS

MYCode:

   

#include<iostream>
#include<cstring>
#include<cstdio>
const int MAXN=1050;
int uN,vN;  //u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool map[35][35];
int n,m;
bool dfs(int u)
{
    int v;
    for(v=1;v<=vN;v++)
        if(g[u][v]&&!used[v])
        {
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    return false;
}
int hungary()
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=1;u<=uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))  res++;
    }
    return res;
}
int main()
{
    int k;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        //init();
        //memset(linker,-1,sizeof(linker));
        memset(g,0,sizeof(g));
        int i,j;
        int x,y;
        for(i=1;i<=k;i++)
        {
            scanf("%d%d",&x,&y);
            map[y][x]=1;
        }
        if((n*m-k)%2)
        {
            printf("NO\n");
            continue;
        }
        int id1,id2;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(!map[i][j])
                {
                    id1=(i-1)*m+j;
                    if(j>1&&!map[i][j-1])
                    {
                        id2=id1-1;
                        //add(id1,id2);
                        g[id1][id2]=1;
                    }
                    if(j<m&&!map[i][j+1])
                    {
                        id2=id1+1;
                        //add(id1,id2);
                        g[id1][id2]=1;
                    }
                    if(i>1&&!map[i-1][j])
                    {
                        id2=id1-m;
                        //add(id1,id2);
                        g[id1][id2]=1;
                    }
                    if(i<n&&!map[i+1][j])
                    {
                        id2=id1+m;
                        //add(id1,id2);
                        g[id1][id2]=1;
                    }
                }
            }
        }
        uN=vN=m*n;
        int res=hungary()/2;
        //cout<<"res="<<res<<endl;
        if(res!=(n*m-k)/2)
        {
            printf("NO\n");
        }
        else
        printf("YES\n");
    }
}

//1032MS

都是二分匹配,思路相同,邻接表16MS,邻接矩阵1032MS,可见邻接矩阵在处理稀疏图方面是不行的.
 

    

原文地址:https://www.cnblogs.com/java20130725/p/3215885.html