ZOJ1516.Uncle Tom's Inherited Land——二分匹配,构图

来源:互联网 发布:算法 pdf 编辑:程序博客网 时间:2024/05/16 00:33

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=516

转http://blog.sina.com.cn/s/blog_7d3ee9f501015amd.html

题目描述:
你的老叔叔Tom 从他的老老叔叔那里继承过来一块土地。最初,这块土地是长方形的。然而,很久以前,他的老老叔叔决定把这块土地分成方形土地的网格。他将其中的一些方块挖成池塘,因为他喜欢打猎,所以他想把野鸭吸引到他的池塘里来。由于池塘挖得太多了,导致在土地里可能形成了一些不连通的小岛。
Tom 想卖掉这块土地,但当地政府对不动产的出售有相应的政策。你的叔叔被告知,依照他的老老叔叔的要求,这块土地只能以两块方块土地组成的长方形土地块起进行出售,而且,池塘是不许卖的。你的叔叔请你帮忙计算他可以出售的最大长方形土地块数目(没卖出的方块土地将被规划成休闲公园)。

就是一个矩形,求用1*2的白色块填充它,求最多能用的白色块

//C++0x 0   756#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>const int MAXN=110;using namespace std;int n,m,k;int pic[MAXN][MAXN];int d[4][2]={0,1,0,-1,1,0,-1,0};int nx,ny;int xs[MAXN][MAXN],ys[MAXN][MAXN];vector<int> g[MAXN*MAXN];int from[MAXN*MAXN],tot;bool use[MAXN*MAXN];bool match(int x){    for(int i=0;i<g[x].size();++i){        if(!use[g[x][i]]){            use[g[x][i]]=true;            if(from[g[x][i]]==-1||match(from[g[x][i]])){                from[g[x][i]]=x;                return true;            }        }    }    return false;}int hungary(){    tot=0;    memset(from,0xff,sizeof(from));    for(int i=1;i<=nx;++i){        memset(use,0,sizeof(use));        if(match(i))            tot++;    }    return tot;}void addedge(int x,int y){    for(int i=0;i<4;++i){        int xx=x+d[i][0];        int yy=y+d[i][1];        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&ys[xx][yy])            g[xs[x][y]].push_back(ys[xx][yy]);    }}int main(){//#ifndef ONLINE_JUDGE//freopen("in.cpp","r",stdin);//freopen("out.cpp","w",stdout);//#endif // ONLINE_JUDGE    int u,v;    while(scanf("%d%d",&n,&m),n,m){        memset(pic,0,sizeof(pic));        memset(xs,0,sizeof(xs));        memset(ys,0,sizeof(ys));        scanf("%d",&k);        while(k--){            scanf("%d%d",&u,&v);            pic[u][v]=1;        }        nx=ny=0;        for(int i=1;i<=n;++i){            for(int j=1;j<=m;++j){                if(!pic[i][j]){                    if((i+j)&1) xs[i][j]=++nx;                    else ys[i][j]=++ny;                }            }        }        for(int i=1;i<=n;++i){            for(int j=1;j<=m;++j){                if(xs[i][j]){                    g[xs[i][j]].clear();                    addedge(i,j);                }            }        }        printf("%d\n",hungary());    }    return 0;}
0 0
原创粉丝点击