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;
}
posted @ 2014-03-30 15:46  forever97  阅读(253)  评论(0编辑  收藏  举报