HDU 4619 Warm up 2 (二分图最小覆盖集)
2016-02-14 15:58
435 查看
题意:给你两种纸牌 ,一种水平放置共有n张,一种竖直放置共有m张,他们被放在一个无限大的网格平面上。水平放置的纸牌占据点(x, y)和(x + 1 , y) , 竖直放置的纸牌占据点(x , y) 和 (x , y + 1)。水平放置的牌之间不会重叠,竖直放置的牌之间也不会重叠,但是水平放置的牌和竖直放置的牌之间可能会重叠。让你拿走一些牌,使剩下的牌之间不会重叠并且数量最多,输出剩余的最大牌数。
思路:把所有水平的骨牌放到二分图左点集,竖直骨牌放在二分图右点集.
如果左(水平)骨牌i与右(竖直)骨牌j有重叠部分,那么就在左i与右j之间连一条无向边. 所以新的二分图中每条边都代表了一个重叠的坐标位置.我们必须在每个重叠的位置上选择拿掉水平骨牌或是竖直骨牌来使得所有骨牌不重叠.(其实就是在二分图的左边或右边选每条边的端点抛弃).为了使得剩下的骨牌最多,我们移除的重叠骨牌必须最少,那么这个问题就是求二分图的最小覆盖集最终n+m-最小覆盖集数=
剩下的骨牌最大数目.
Description
Some 1×2 dominoes are placed on a plane. Each dominoe is placed either horizontally or vertically. It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each
other. You task is to remove some dominoes, so that the remaining dominoes do not overlap with each other. Now, tell me the maximum number of dominoes left on the board.
Input
There are multiple input cases.
The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
Input ends with n = 0 and m = 0.
Output
For each test case, output the maximum number of remaining dominoes in a line.
Sample Input
Sample Output
思路:把所有水平的骨牌放到二分图左点集,竖直骨牌放在二分图右点集.
如果左(水平)骨牌i与右(竖直)骨牌j有重叠部分,那么就在左i与右j之间连一条无向边. 所以新的二分图中每条边都代表了一个重叠的坐标位置.我们必须在每个重叠的位置上选择拿掉水平骨牌或是竖直骨牌来使得所有骨牌不重叠.(其实就是在二分图的左边或右边选每条边的端点抛弃).为了使得剩下的骨牌最多,我们移除的重叠骨牌必须最少,那么这个问题就是求二分图的最小覆盖集最终n+m-最小覆盖集数=
剩下的骨牌最大数目.
#include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn=1000+50; struct Max_Match { int n,m; int g[maxn][maxn]; bool vis[maxn]; int left[maxn]; void init(int n,int m) { this->n=n; this->m=m; memset(left,-1,sizeof(left)); memset(g,0,sizeof(g)); } bool match(int u) { for(int v=1;v<=m;v++) { if(g[u][v] && !vis[v]) { vis[v]=true; if(left[v]==-1 || match(left[v])) { left[v]=u; return true; } } } return false; } int solve() { int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(match(i)) ans++; } return ans; } }MM; int T; int cas = 1; struct Node { int x1,y1; int x2,y2; Node(){} Node(int x1,int y1,int x2,int y2):x1(x1),y1(y1),x2(x2),y2(y2){} }node1[maxn],node2[maxn]; bool check(int i,int j) { if (node1[i].x1==node2[j].x1 && node1[i].y1==node2[j].y1) return true; else if (node1[i].x1 == node2[j].x2 && node1[i].y1==node2[j].y2) return true; else if (node1[i].x2==node2[j].x1 && node1[i].y2==node2[j].y1) return true; else if (node1[i].x2==node2[j].x2 && node1[i].y2==node2[j].y2) return true; return false; } int main() { int n,m; while (scanf("%d%d",&n,&m)!=EOF && n) { MM.init(n,m); for (int i = 1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); node1[i]=Node(x,y,x+1,y); } for (int i = 1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); node2[i]=Node(x,y,x,y+1); } for (int i = 1;i<=n;i++) for (int j = 1;j<=m;j++) { if (check(i,j)) MM.g[i][j]=1; } printf("%d\n",n+m-MM.solve()); } return 0; }
Description
Some 1×2 dominoes are placed on a plane. Each dominoe is placed either horizontally or vertically. It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each
other. You task is to remove some dominoes, so that the remaining dominoes do not overlap with each other. Now, tell me the maximum number of dominoes left on the board.
Input
There are multiple input cases.
The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
Input ends with n = 0 and m = 0.
Output
For each test case, output the maximum number of remaining dominoes in a line.
Sample Input
2 3 0 0 0 3 0 1 1 1 1 3 4 5 0 1 0 2 3 1 2 2 0 0 1 0 2 0 4 1 3 2 0 0
Sample Output
4 6
相关文章推荐
- Android开发中无处不在的设计模式——Builder模式
- 修改Windows系统盘盘符
- C# 数据类型
- epool如何高效
- Maven实战(Maven+Nexus建立私服【Linux系统】)
- iOS单例
- symlink,symlinkat,readlink and readlinkat
- 《那些年入上百万的人是如何做到的》读后感
- listview的头布局把我的ACTION_DOWN事件给吃了.....
- ANDROID_MARS学习笔记_S01原始版_009_下载文件
- Android电话事件案例
- 全面复习之SQL(7)-数据控制语句
- 点分治练习:不虚就是要AK
- User: root is not allowed to impersonate admin
- EJB远程调用和本地调用
- ADO.NET基础
- 评论回复jQuery实现前端效果
- iOS IM开发blog写作计划
- Reverse Integer
- 蓝桥杯 历届试题 分糖果