• poj2446_二分图


    POJ 2446  二分图的最大匹配 匈牙利算法

    Chessboard
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 14350   Accepted: 4471

    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

    题意:用2*1的木板覆盖给定的棋盘(棋盘中有墙),木板不能重叠,问是否能全部覆盖
    思路:奇偶建二分图,把棋盘涂成黑白相间,每个黑格和4个白格相邻,每个白格和四个黑格相邻,黑格移入U,白格移入V,求最大匹配,由于每个匹配对应两个结点,若最大匹配*2等于总结点数说明成功覆盖
    /* poj2446 141ms  */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    
    const int maxn=1200;
    
    int N,M,K;
    int uN,vN;
    vector<int> G[maxn];
    int link[maxn];
    bool vis[maxn];
    int ch[maxn][maxn];
    int dx[]={-1,1,0,0};
    int dy[]={0,0,-1,1};
    
    bool dfs(int u)
    {
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(!vis[v]){
                vis[v]=1;
                if(link[v]==-1||dfs(link[v])){
                    link[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hungary()
    {
        int res=0;
        memset(link,-1,sizeof(link));
        for(int u=1;u<=uN;u++){
            memset(vis,0,sizeof(vis));
            if(dfs(u)) res++;
        }
        return res;
    }
    
    int main()
    {
        cin>>N>>M>>K;
        for(int i=1;i<=N*M;i++) G[i].clear();
        memset(ch,-1,sizeof(ch));
        uN=vN=0;
        while(K--){
            int i,j;
            scanf("%d%d",&j,&i);
            ch[i][j]=0;
        }
        for(int i=1;i<=N;i++){
            for(int j=1;j<=M;j++){
                if(ch[i][j]){
                    if((i+j)%2) ch[i][j]=++uN;
                    else ch[i][j]=++vN;
                }
            }
        }
        for(int i=1;i<=N;i++){
            for(int j=1;j<=M;j++){
                if(ch[i][j]&&ch[i][j]!=-1&&(i+j)%2){
                    for(int k=0;k<4;k++){
                        int x=i+dx[k],y=j+dy[k];
                        if(ch[x][y]&&ch[x][y]!=-1) G[ch[i][j]].push_back(ch[x][y]);
                    }
                }
            }
        }
        int match=hungary();
        if(match*2==uN+vN) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    Linux系统、版本、CPU、内存查看、硬盘空间
    Spring AOP 通过order来指定顺序
    关于 String.intern() 的思考
    java枚举类型构造方法为什么是private的
    Spring Cache 介绍
    Linux下redis的安装
    使用Spring实现读写分离( MySQL实现主从复制)
    Intellij Idea 13 快捷键(与Eclipse比对)以及基本的设置
    linux下tomcat的shutdown命令杀不死进程
    求N个元素的子集合个数
  • 原文地址:https://www.cnblogs.com/--560/p/4337620.html
Copyright © 2020-2023  润新知