POJ 3020 -Antenna Placement-二分图匹配
题意:一个N*M的矩阵里有K个观测点,你必须放置天线覆盖所有观测点。每个雷达只能天线两个观测点,这两点必须相邻。计算最少天线数。
做法:将所有相邻的观测点连起来,建图。跑一遍匈牙利算法就计算出了最大的覆盖数,除以二就是天线数。还要加上落单的观测点,每个都需要一个天线。
1 /*--------------------------------------------------------------------------------------*/ 2 // Helica's header 3 // Second Edition 4 // 2015.11.7 5 // 6 #include <algorithm> 7 #include <iostream> 8 #include <cstring> 9 #include <ctype.h> 10 #include <cstdlib> 11 #include <cstdio> 12 #include <vector> 13 #include <string> 14 #include <queue> 15 #include <stack> 16 #include <cmath> 17 #include <set> 18 #include <map> 19 20 //debug function for a N*M array 21 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\ 22 {for(int j=0;j<(M);j++){\ 23 printf("%d",G[i][j]);}printf("\n");} 24 //debug function for int,float,double,etc. 25 #define debug_var(X) cout<<#X"="<<X<<endl; 26 /*--------------------------------------------------------------------------------------*/ 27 using namespace std; 28 29 const int maxn = 100; 30 int N,M,T; 31 int G[10*maxn][10*maxn],Map[maxn][maxn]; 32 int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 33 int linker[10*maxn]; 34 bool used[10*maxn]; 35 int uN,vN; 36 37 bool dfs(int u) 38 { 39 for(int v=1;v<=vN;v++) 40 { 41 if(G[u][v] && !used[v]) 42 { 43 used[v] = true; 44 if(linker[v] == -1 || dfs(linker[v])) 45 { 46 linker[v] = u; 47 return true; 48 } 49 } 50 } 51 return false; 52 } 53 54 int hungary() 55 { 56 memset(linker,-1,sizeof linker); 57 int res = 0; 58 for(int u=1;u<=uN;u++) 59 { 60 memset(used,false,sizeof used); 61 if(dfs(u)) res++; 62 } 63 return res; 64 } 65 66 int main() 67 { 68 scanf("%d",&T); 69 while(T--) 70 { 71 scanf("%d%d",&N,&M); 72 char c; 73 uN = 0; 74 for(int i=0;i<N;i++) 75 { 76 getchar(); 77 for(int j=0;j<M;j++) 78 { 79 scanf("%c",&c); 80 if(c == '*') Map[i][j] = ++uN; 81 else Map[i][j] = 0; 82 } 83 } 84 memset(G,0,sizeof G); 85 vN = uN; 86 for(int i=0;i<N;i++) 87 { 88 for(int j=0;j<M;j++) if(Map[i][j]) 89 { 90 int u = Map[i][j]; 91 for(int p=0;p<4;p++) 92 { 93 int nx = i+dx[p],ny = j+dy[p]; 94 if(nx >=0 && nx < N && ny >=0 && ny < M) 95 { 96 if(int v = Map[nx][ny]) 97 { 98 //printf("u:%d v:%d\n",u,v); 99 G[u][v] = G[v][u] = 1; 100 } 101 } 102 } 103 } 104 } 105 106 int ans = hungary(); 107 //printf("ans:%d uN:%d\n",ans,uN); 108 printf("%d\n",(uN-ans)+ans/2); 109 } 110 }