【二分图+最小路径覆盖】北大 poj 3020 Antenna Placement

来源:互联网 发布:肛门调教知乎 编辑:程序博客网 时间:2024/05/21 09:15


/* THE PROGRAM IS MADE BY PYY *//*----------------------------------------------------------------------------//Copyright (c) 2011 panyanyany All rights reserved.URL   : http://poj.org/problem?id=3020Name  : 3020 Antenna PlacementDate  : Thursday, December 8, 2011Time Stage : one hourResult: 9644820panyanyany3020Accepted184K0MSC++1588B2011-12-08 20:31:01Test Data :Review :不知道为什么是最小路径覆盖(也有一种说法是最大独立集),不理解,求大牛指点….我看到很多人是把它转化为一个标准的二分图来做的……这其实也是一种思路,不过我觉得那样有点麻烦,就没有去做……貌似也是因为我没有想到这样做……//----------------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#define MAXSIZE43struct POINT {int x, y ;};intn, h, w ;boolcover[MAXSIZE][MAXSIZE] ;charmap[MAXSIZE][MAXSIZE] ;chardir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1} ;POINTlink[MAXSIZE][MAXSIZE] ;bool find (int py, int px){int i, j ;int x, y ;for (i = 0 ; i < 4 ; ++i){y = py + dir[i][0] ;x = px + dir[i][1] ;if ((0 < x && x <= w && 0 < y && y <= h) &&!cover[y][x] &&(map[y][x] == '*')){cover[y][x] = true ;if (!link[y][x].x || find (link[y][x].y, link[y][x].x)){link[y][x].y = py ;link[y][x].x = px ;return true ;}}}return false ;}int main (){int i, j ;int x, y ;int sum, cnt ;while (~scanf ("%d", &n)){while (n--){scanf ("%d%d", &h, &w) ;for (j = 1 ; j <= h ; j++){scanf ("%s", &map[j][1]) ;}sum = cnt = 0 ;memset (link, 0, sizeof (link)) ;for (j = 1 ; j <= h ; ++j)for (i = 1 ; i <= w ; ++i){if (map[j][i] == '*'){++ cnt ;memset (cover, 0, sizeof (cover)) ;sum += find (j, i) ;}}printf ("%d\n", cnt - sum / 2) ;}}return 0 ;}