zoukankan      html  css  js  c++  java
  • 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement

    题目传送门

      1 /*
      2     题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个
      3     匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据
      4 */
      5 #include <cstdio>
      6 #include <algorithm>
      7 #include <cstring>
      8 #include <vector>
      9 using namespace std;
     10 
     11 const int MAXN = 4e2 + 10;
     12 const int INF = 0x3f3f3f3f;
     13 char s[44][11];
     14 int ha[44][11];
     15 bool vis[MAXN];
     16 int lk[MAXN];
     17 vector<int> G[MAXN];
     18 int dx[4] = {-1, 1, 0, 0};
     19 int dy[4] = {0, 0, -1, 1};
     20 int un, vn;
     21 
     22 bool DFS(int u)
     23 {
     24     for (int i=0; i<G[u].size (); ++i)
     25     {
     26         int v = G[u][i];
     27         if (!vis[v])
     28         {
     29             vis[v] = true;
     30             if (lk[v] == -1 || DFS (lk[v]))
     31             {
     32                 lk[v] = u;  return true;
     33             }
     34         }
     35     }
     36 
     37     return false;
     38 }
     39 
     40 int hungary(void)
     41 {
     42     int res = 0;    memset (lk, -1, sizeof (lk));
     43     for (int i=1; i<=un; ++i)
     44     {
     45         memset (vis, false, sizeof (vis));
     46         if (DFS (i))    res++;
     47     }
     48 
     49     return res;
     50 }
     51 
     52 int main(void)        //POJ 3020 Antenna Placement
     53 {
     54     //freopen ("POJ_3020.in", "r", stdin);
     55 
     56     int t;  scanf ("%d", &t);
     57     while (t--)
     58     {
     59         int h, w;   scanf ("%d%d", &h, &w);
     60         for (int i=1; i<=h; ++i)
     61         {
     62             scanf ("%s", s[i] + 1);
     63         }
     64 
     65         un = vn = 0;
     66         for (int i=1; i<=h; ++i)
     67         {
     68             for (int j=1; j<=w; ++j)
     69             {
     70                 if (s[i][j] == '*')
     71                 {
     72                     if ((i+j) & 1)  ha[i][j] = ++un;
     73                     else    ha[i][j] = ++vn;
     74                 }
     75             }
     76         }
     77 
     78         for (int i=1; i<=un; ++i)   G[i].clear ();
     79 
     80         for (int i=1; i<=h; ++i)
     81         {
     82             for (int j=1; j<=w; ++j)
     83             {
     84                 if (s[i][j] == '*' && (i+j) & 1)
     85                 {
     86                     for (int k=0; k<4; ++k)
     87                     {
     88                         int tx = i + dx[k]; int ty = j + dy[k];
     89                         if (tx >= 1 && tx <= h && ty >= 1 && ty <= w && s[tx][ty] == '*')
     90                             G[ha[i][j]].push_back (ha[tx][ty]);
     91                     }
     92                 }
     93             }
     94         }
     95 
     96         printf ("%d
    ", un + vn - hungary ());
     97     }
     98 
     99     return 0;
    100 }
    编译人生,运行世界!
  • 相关阅读:
    Python超轻量数据库之SQLite
    Docker镜像管理透析
    Docker-Compose实战「下篇」
    Docker-Compose实战「上篇」
    Docker-Compose初体验
    Docker火遍全球!dockerfile构建你必须得会
    Docker轻量管理Dashboard
    MongoDB入门实操《上篇》
    用LinkedList完成一个堆栈MyStack.2
    [翻译] 基于.NET Core构建微服务 第五部分:Marten域聚合的理想仓库
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4652282.html
Copyright © 2011-2022 走看看