pku3020 Antenna Placement

http://poj.org/problem?id=3020

二分图匹配,匈牙利算法(dfs+邻接矩阵)

建图:相邻点双向连接,建无向图

结果(最少需要的“圈”数) ==(总点数 - 最大匹配数)/*没有匹配成功的点需要自己单独一个“圈”*/  +  (最大匹配数 / 2) /*匹配成功的点,2个点共用一个"圈"*/

化简为:结果 == 总点数 - (最大匹配数 / 2)

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 432
 4 
 5 int n, m;
 6 int map[N][N], flag[N], girl[N];
 7 
 8 int find(int x)
 9 {
10     int i;
11     for(i=1; i<=n*m; i++)
12     {
13         if(!flag[i] && map[x][i])
14         {
15             flag[i] = 1;
16             if(girl[i]==-1 || find(girl[i]))
17             {
18                 girl[i] = x;
19                 return 1;
20             }
21         }
22     }
23     return 0;
24 }
25 
26 int main()
27 {
28     int t, i, j, k, p, q, temp, sum, count;
29     int dir[4][2] = {1,0,0,1,-1,0,0,-1},map1[43][12];
30     char c;
31     scanf("%d", &t);
32     while(t-- && scanf("%d%d%*c", &n, &m))
33     {
34         count = 0;
35         for(i=1; i<=n; i++)
36         {
37             for(j=1; j<=m; j++)
38             {
39                 scanf("%c", &c);
40                 map1[i][j] = c-'o'? (++count,1): 0;
41             }
42             getchar();
43         }
44         temp = n*m;
45         for(i=1; i<=temp; i++)
46         {
47             girl[i] = -1;
48             for(j=1; j<=temp; j++)
49             {
50                 map[i][j] = 0;
51             }
52         }
53         for(i=1; i<=n; i++)
54         {
55             for(j=1; j<=m; j++)
56             {
57                 if(map1[i][j])
58                 {
59                     temp = m*(i-1) + j;
60                     //printf("%d: ", temp);
61                     for(k=0; k<4; k++)
62                     {
63                         p = i + dir[k][0];
64                         q = j + dir[k][1];
65                         if(p<1 || p>n || q<1 || q>m)
66                         {
67                             continue;
68                         }
69                         if(map1[p][q])
70                         {
71                             //printf("(%d, %d) ", p, q);
72                             map[temp][m*(p-1)+q] = 1;
73                         }
74                     }
75                     //printf("\n");
76                 }
77             }
78         }
79         temp = n*m;
80         sum = 0;
81         for(i=1; i<=temp; i++)
82         {
83             for(j=1; j<=temp; j++)
84             {
85                 //printf("%d ", map[i][j]);
86                 flag[j] = 0;
87             }
88             //printf("\n");
89             sum += find(i);
90         }
91         printf("%d\n", count-sum/2);
92     }
93     return 0;
94 }
原文地址:https://www.cnblogs.com/yuan1991/p/pku3020.html