二分图最大匹配_基础 - Chessboard

来源:互联网 发布:火眼金睛 软件 编辑:程序博客网 时间:2024/05/21 21:46

题意:给定一个M*N的长方形,要求用1*2的小长方形填充,但是其中有些小方格被挖了洞,现在问是否可以将所有的空格填充完。

想法:

简单的而二分图的模板题。
建图方法好像不唯一。
我是把每个空格子当成一个点。
然后对于每个格子如果可以往上、下、左、右去找可以建立的边。
然后求最大匹配,如果最大匹配数刚好等于空格子数,输出YES,否则NO。


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.
代码:#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1060;
int n1,n2;
int _map[N][N];
bool vis[N];
int llink[N];
int find(int x) {
    int i;
    for(i=0; i<n2; i++) {
        if(_map[x][i]&&!vis[i]) {
            vis[i]=true;


            if(llink[i]==-1||find(llink[i])) {
                llink[i]=x;
                return true;
            }
        }
    }
    return false;
}


int mach() {
    int ans=0;
    memset(llink,-1,sizeof(llink));
    for(int i=0; i<n1; i++) {
        memset(vis,false,sizeof(vis));
        if(find(i)) {
            ans++;
        }
    }
    return ans;
}
int main() {
    int k;
    int x,y;
    int n,m;
    bool tmp_map[50][50];
    int num[50][50];
    while(~scanf("%d%d%d",&m,&n,&k)) {
        memset(_map,0,sizeof(_map));
        memset(tmp_map,false,sizeof(tmp_map));
        for(int i=0; i<k; i++) {
            scanf("%d%d",&x,&y);
            x--;
            y--;
            tmp_map[y][x]=true;
        }
        int tol=0;
        for(int i=0; i<m; i++) {
            for(int j=0; j<n; j++) {
                if(tmp_map[i][j]==false) {
                    num[i][j]=tol++;
                }
            }
        }
        n1=n2=tol;
        for(int i=0; i<m; i++) {
            for(int j=0; j<n; j++) {
                if(!tmp_map[i][j]) {
                    int u=num[i][j];
                    if(i>0&&!tmp_map[i-1][j]) {
                        _map[u][num[i-1][j]]=1;
                    }
                     if(j>0&&!tmp_map[i][j-1]) {
                        _map[u][num[i][j-1]]=1;
                    }
                     if(i<m-1&&!tmp_map[i+1][j]) {
                        _map[u][num[i+1][j]]=1;
                    }
                     if(j<n-1&&!tmp_map[i][j+1]) {
                        _map[u][num[i][j+1]]=1;
                    }
                }
            }
        }
     //printf("%d   %d\n",mach(),tol);
      if(mach()==tol){
        printf("YES\n");
      }else{
        printf("NO\n");
      }


    }
    return 0;
}

0 0