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 }