HDU 1507 Uncle Tom's Inherited Land*

题目大意:给你一个矩形,然后输入矩形里面池塘的坐标(不能放东西的地方),问可以放的地方中,最多可以放多少块1*2的长方形方块,并输出那些方块的位置。

题解:我们将所有未被覆盖的分为两种,即分为黑白格(i+j结果为奇数和偶数),然后将相邻的连边,做一遍最大匹配即可。

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

using namespace std;

const int N=105;

vector v[N];

int q,w,m,n,k,odd,even,oddx[N],evenx[N],oddy[N],eveny[N],used[N],link[N];

int map[N][N];

struct node{int x,y,x1,y1;}ans[N];

int abs(int a){return a>0?a:-a;}

bool Dfs(int k){

    for(int i=0;i<v[k].size();i++){

        int a=v[k][i];

        if(used[a]==0){

            used[a]=1;

            if(link[a]==-1||Dfs(link[a])){link[a]=k;return 1;}

        } 

    }return 0;

}

bool cmp(node a,node b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}

int main(){

    while(scanf("%d%d",&n,&m),n!=0&&m!=0){

        for(int i=0;i<N;i++)v[i].clear();

        scanf("%d",&k); odd=even=0;

        memset(map,0,sizeof(map));

        for(int i=0;i<k;i++)scanf("%d%d",&q,&w),map[q][w]=1;

        for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)if(!map[i][j]){

            if((i+j)%2==0)evenx[++even]=i,eveny[even]=j;

            else{oddx[++odd]=i;oddy[odd]=j;}

        }

        for(int i=1;i<=odd;i++)

        for(int j=1;j<=even;j++){

            if(oddx[i]==evenx[j]&&abs(oddy[i]-eveny[j])==1)v[j].push_back(i);

            if(oddy[i]==eveny[j]&&abs(oddx[i]-evenx[j])==1)v[j].push_back(i);  

            }int count=0;

        memset(link,-1,sizeof(link));

        for(int i=1;i<=even;i++){

            memset(used,0,sizeof(used));

            if(Dfs(i))count++;

        }int cnt=0;

        printf("%d\n",count);

        for(int i=1;i<=odd;i++){

            if(link[i]!=-1){

                if(oddx[i]<evenx[link[i]]||(oddx[i]==evenx[link[i]]&&oddy[i]<eveny[link[i]])){

                    ans[cnt].x=oddx[i];ans[cnt].y=oddy[i];

                    ans[cnt].x1=evenx[link[i]];ans[cnt++].y1=eveny[link[i]];

                }else{

                    ans[cnt].x1=oddx[i];ans[cnt].y1=oddy[i];

                    ans[cnt].x=evenx[link[i]];ans[cnt++].y=eveny[link[i]];

                }

            }

        }

        sort(ans,ans+cnt,cmp);

        for(int i=0;i<cnt;i++)printf("(%d,%d)--(%d,%d)\n",ans[i].x,ans[i].y,ans[i].x1,ans[i].y1);

    }

    return 0;

}

你可能感兴趣的:(Inherit)