HDU4619

来源:互联网 发布:器灵网络剧百度云资源 编辑:程序博客网 时间:2024/05/29 10:33
/*m+n-二分匹配题目大意:给出横纵放置的多米诺骨牌,相同方向的不会重叠,不同方向的可能重叠,问去掉一些重叠的排,使得留在桌上的数量最大</P>解题方法:m+n-二分匹配</P>因为重叠的数目是一定的,但是一张排可能与多张重叠,所以暴力比较费劲,直接用二分匹配找出重叠的对数,相当于要去掉的个数,所以输入以后判断有哪些是互相重合的,然后初始化map为1*/#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=1010;int map[maxn][maxn];int link[maxn];bool use[maxn];int uN,vN;struct v{int x,y;}v[maxn],h[maxn];bool dfs(int u){int v;for(v=1;v<=vN;v++){if(map[u][v]&&!use[v]){use[v]=true;if(link[v]==-1 || dfs(link[v]) ){link[v]=u;return true;}}}return false;}int hungre(){int u;int ans=0;memset(link,-1,sizeof(link));for(u=1;u<=uN;u++){memset(use,false,sizeof(use));if(dfs(u)) ans++;}return ans;}bool check(int i , int j){    if(h[i].x <= v[j].x && v[j].x <= h[i].x + 1){        if(v[j].y <= h[i].y && v[j].y + 1 >= h[i].y){            return 1 ;        }    }    return 0 ;}int main(){int i,j,n,m;while(scanf("%d%d",&n,&m)&& (n || m) ){for(i=1;i<=n;i++)scanf("%d%d",&h[i].x,&h[i].y);for(i=1;i<=m;i++)scanf("%d%d",&v[i].x,&v[i].y);memset(map,0,sizeof(map));vN=m;uN=n;for(i=1;i<=n;i++)for(j=1;j<=m;j++){   if(check(i,j) ) map[i][j]=1;}int sum=hungre();printf("%d\n",n+m-sum);}return 0;}

原创粉丝点击