HDU 4619 Warm up 2 (2013 多校第二场) - from lanshui_Yang
2013-08-02 14:16
120 查看
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each test case, output the maximum number of remaining dominoes in a line.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each test case, output the maximum number of remaining dominoes in a line.
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
4 6 题目大意:给你两种纸牌 ,一种水平放置共有n张 ,一种竖直放置共有m张。水平放置的纸牌占据点(x, y)和(x + 1 , y) , 竖直放置的纸牌占据点(x , y) 和 (x , y + 1)。水平放置的牌之间不会重叠,竖直放置的牌之间也不会重叠,但是水平放置的牌和竖直放置的牌之间可能会重叠。让你拿走一些牌,使剩下的牌之间不会重叠并且数量最多,输出剩余的最大牌数。 解题思路:这是一道典型的二分图匹配问题,先是建图:水平放置的牌放入集合ho{}中,竖直放置的牌放入集合ve{}中,重叠的牌之间建立一条边。图建好后,求出图的最大匹配数 , 然后由二分图的点独立数 = 顶点个数 - 匹配数 得到点独立数 即是答案。 请看代码:#include<iostream> #include<cstring> #include<string> #include<cmath> #include<cstdio> #include<algorithm> using namespace std ; const int MAXN = 1111 ; struct point { int x ; int y ; } ho[MAXN] , ve[MAXN]; int g[MAXN][MAXN] ; int cx[MAXN] ; int cy[MAXN] ; int vis[MAXN] ; int n , m ; int path(int v) // 匈牙利算法 { int i ; for(i = 0 ; i < m ; i ++) { if(g[v][i] == 1 && !vis[i]) { vis[i] = 1 ; if(cy[i] == -1 || path(cy[i])) { cy[i] = v ; cx[v] = i ; return 1 ; } } } return 0 ; } int pi(point a , point b) // 判断是否重叠 { if(a.x == b.x && a.y == b.y) return 1 ; if(a.x == b.x && a.y == b.y + 1) return 1 ; if(a.x + 1 == b.x && a.y == b.y) return 1 ; if(a.x + 1 == b.x && a.y == b.y + 1) return 1 ; return 0 ; } void init() { while (cin >> n >> m) { if(n == 0 && m == 0) break ; memset(g , 0 , sizeof(g)) ; memset(cx , -1 , sizeof(cx)) ; // 均初始化为-1 ,代表此点未被覆盖 memset(cy , -1 , sizeof(cy)) ; int i , j ; for(i = 0 ; i < n ; i ++) { scanf("%d%d" , &ho[i].x , &ho[i].y) ; } for(j = 0 ; j < m ; j ++) { scanf("%d%d" , &ve[j].x , &ve[j].y) ; } for(i = 0 ; i < n ; i ++) { for(j = 0 ; j < m ; j ++) if(pi(ho[i] , ve[j])) { g[i][j] = 1 ; // 建图,注意这里千万不能写成 g[i][j] = g[j][i] = 1 !! } } int ans = 0 ; // 记录匹配数 for(i = 0 ; i < n ; i ++) { if(cx[i] == -1) // 如果 第i张 水平放置 的牌未被覆盖 , 就从此点出发寻找增广路 { memset(vis , 0 ,sizeof(vis)) ; ans += path(i) ; } } printf("%d\n" , n + m - ans) ; } } int main() { init() ; return 0 ; }
相关文章推荐
- hdu 4619 warm up 2 并查集或搜索都可以做出来的题 2013多校联合训练第二场
- 2013 多校第二场 hdu 4619 Warm up 2
- hdu 4619 Warm up 2 多校第二场
- 2013 多校第二场 hdu 4612 Warm up
- HDU 4619 Warm up 2(2013多校2 1009 二分匹配)
- hdu 4617 2013多校联合训练第二场weapon简单的计算几何
- 2013 多校9 1005 EBCDIC - from lanshui_Yang
- 2013多校联合2 I Warm up 2(hdu 4619)
- 2013 多校第二场 hdu 4618 Palindrome Sub-Array
- 2013 多校第二场 hdu 4617 Weapon
- 2013 多校第二场 hdu 4614 Vases and Flowers(线段树)
- 2013 多校第二场 hdu 4611 Balls Rearrangement
- 2013 多校第二场 hdu 4620 Fruit Ninja Extreme
- 2013多校联合2 I Warm up 2(hdu 4619)
- 2013 多校第二场 hdu 4616 Game
- HDU 4619 Warm up 2 (多校)
- 2013 多校总结 - from lanshui_Yang
- HDU 4612 Warm up(2013多校2 1002 双连通分量)
- HDU 2255(KM) - from lanshui_Yang
- hdu 4619 Warm up 2(并查集活用)