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 }

 

你可能感兴趣的:(POJ 3020 -Antenna Placement-二分图匹配)