/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2011 panyanyany All rights reserved. URL : http://poj.org/problem?id=3020 Name : 3020 Antenna Placement Date : Thursday, December 8, 2011 Time Stage : one hour Result: 9644820 panyanyany 3020 Accepted 184K 0MS C++ 1588B 2011-12-08 20:31:01 Test Data : Review : 不知道为什么是最小路径覆盖(也有一种说法是最大独立集),不理解,求大牛指点…. 我看到很多人是把它转化为一个标准的二分图来做的……这其实也是一种思路,不过我觉得 那样有点麻烦,就没有去做……貌似也是因为我没有想到这样做…… //----------------------------------------------------------------------------*/ #include <stdio.h> #include <string.h> #define MAXSIZE 43 struct POINT { int x, y ; }; int n, h, w ; bool cover[MAXSIZE][MAXSIZE] ; char map[MAXSIZE][MAXSIZE] ; char dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1} ; POINT link[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 ; }