zoukankan      html  css  js  c++  java
  • 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("
    ");for(int i=0;i<(N);i++)
     22 {for(int j=0;j<(M);j++){
     23 printf("%d",G[i][j]);}printf("
    ");}                
     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
    ",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
    ",ans,uN);
    108         printf("%d
    ",(uN-ans)+ans/2);
    109     }    
    110 }
  • 相关阅读:
    跨平台技术
    Unity和虚幻的比较
    商业模式(四):群硕软件,欧美客户为主的软件外包
    商业模式(四):群硕软件,欧美客户为主的软件外包
    Volley完全解析
    双十一京东图书购物清单,动动脑子节省300元
    双十一京东图书购物清单,动动脑子节省300元
    ListView异步加载图片,完美实现图文混排
    使用DrawerLayout实现QQ5.0侧拉菜单效果
    商业模式(三):P2P网贷平台,毛利润测算
  • 原文地址:https://www.cnblogs.com/helica/p/5243946.html
Copyright © 2011-2022 走看看