POJ 3020 Antenna Placement(二分图匹配)

题目链接

无向二分图的最小路径覆盖 = 顶点数 – 最大二分匹配数/2

看题解过的。看了网上的题解,说是拆点,然后把所有的城市分为两个集合,然后用匈牙利算法计算出最大二分图匹配。

 1 #include <cstdio>

 2 #include <cstring>

 3 using namespace std;

 4 char str[51][51];

 5 int p[501][501],used[501],linker[501],o[51][51];

 6 int x[4] = {0,0,1,-1};

 7 int y[4] = {1,-1,0,0};

 8 int num;

 9 int dfs(int x)

10 {

11     int i;

12     for(i = 1;i <= num;i ++)

13     {

14         if(p[x][i]&&!used[i])

15         {

16             used[i] = 1;

17             if(linker[i] == -1||dfs(linker[i]))

18             {

19                 linker[i] = x;

20                 return 1;

21             }

22         }

23     }

24     return 0;

25 }

26 int main()

27 {

28     int t,i,j,k,ans,n,m,r,c;

29     scanf("%d",&t);

30     while(t--)

31     {

32         memset(p,0,sizeof(p));

33         memset(o,0,sizeof(o));

34         memset(linker,-1,sizeof(linker));

35         scanf("%d%d",&n,&m);

36         num = 1;

37         for(i = 0;i < n;i ++)

38         scanf("%s",str[i]);

39         for(i = 0;i < n;i ++)

40         {

41             for(j = 0;j < m;j ++)

42             {

43                 if(str[i][j] == '*')

44                 o[i][j] = num ++;

45             }

46         }

47         num --;

48         for(i = 0;i < n;i ++)

49         {

50             for(j = 0;j < m;j ++)

51             {

52                 if(str[i][j] == '*')

53                 {

54                     for(k = 0;k <= 3;k ++)

55                     {

56                         r = i + x[k];

57                         c = j + y[k];

58                         if(r >= 0&&r < n&&c >= 0&&c < m&&o[r][c])

59                         {

60                             p[o[r][c]][o[i][j]] = 1;

61                         }

62                     }

63                 }

64             }

65         }

66         ans = 0;

67         for(i = 1;i <= num;i ++)

68         {

69             memset(used,0,sizeof(used));

70             if(dfs(i))

71             ans ++;

72         }

73         printf("%d\n",num-ans/2);

74     }

75     return 0;

76 }

 

你可能感兴趣的:(ant)