题目链接:

https://vjudge.net/problem/ZOJ-1654

题目大意:

有一个N*M(N,M<=50)的棋盘,棋盘的每一格是三种类型之一:空地、草地、墙。机器人只能放在空地上。在同一行或同一列的两个机器人,若它们之间没有墙,则它们可以互相攻击。问给定的棋盘,最多可以放置多少个机器人,使它们不能互相攻击。

解题思路:

和POJ-2226类似

我们将每一行,每一列被墙隔开,且包含空地的连续区域称作“块”。显然,在一个块之中,最多只能放一个机器人,我们把这些块编上号。同样,把竖直方向的块也编上号。如下图:

 

       

 

把每个横向块看作X部的点,竖向块看作Y部的点,若两个块有公共的空地,则在它们之间连边。于是,问题转化成这样的一个二分图:

 


  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<queue>
  7 using namespace std;
  8 typedef pair<int, int> Pair ;
  9 typedef long long ll;
 10 const int INF = 0x3f3f3f3f;
 11 const int maxn = 2500 + 10;
 12 vector<int>G[maxn];
 13 int cx[maxn], cy[maxn];
 14 int cntx, cnty;
 15 bool vis[maxn];
 16
 17 void init(int n)
 18 {
 19     for(int i = 0; i <= n; i++)G[i].clear();
 20 }
 21 bool dfs(int u)
 22 {
 23     for(int i = 0; i < G[u].size(); i++)
 24     {
 25         int v = G[u][i];
 26         if(!vis[v])
 27         {
 28             vis[v] = 1;
 29             if(cy[v] == -1 || dfs(cy[v]))
 30             {
 31                 cx[u] = v;
 32                 cy[v] = u;
 33                 return true;
 34             }
 35         }
 36     }
 37     return false;
 38 }
 39
 40 int maxmatch()
 41 {
 42     memset(cx, -1, sizeof(cx));
 43     memset(cy, -1, sizeof(cy));
 44     int ans = 0;
 45     for(int i = 1; i <= cntx; i++)
 46     {
 47         if(cx[i] == -1)
 48         {
 49             memset(vis, 0, sizeof(vis));
 50             ans += dfs(i);
 51         }
 52     }
 53     return ans;
 54 }
 55 char Map[55][55];
 56 int T, n, m, cases;
 57 void build_Map()
 58 {
 59     //横向标号
 60     int a[55][55], b[55][55];
 61     memset(a, 0, sizeof(a));
 62     memset(b, 0, sizeof(b));
 63     cntx = cnty = 0;
 64     for(int i = 0; i < n; i++)
 65     {
 66         for(int j = 0; j < m; j++)
 67         {
 68             if(Map[i][j] == 'o')
 69             {
 70                 a[i][j] = ++cntx;
 71                 j++;
 72                 while(j < m && Map[i][j] != '#')
 73                     a[i][j] = a[i][j - 1], j++;
 74             }
 75         }
 76     }
 77     //竖向编号
 78     for(int j = 0; j < m; j++)
 79     {
 80         for(int i = 0; i < n; i++)
 81         {
 82             if(Map[i][j] == 'o')
 83             {
 84                 b[i][j] = ++cnty;
 85                 i++;
 86                 while(i < n && Map[i][j] != '#')
 87                     b[i][j] = b[i - 1][j], i++;
 88             }
 89         }
 90     }
 91     init(cntx);//初始化Map
 92     for(int i = 0; i < n; i++)
 93         for(int j = 0; j < m; j++)
 94         if(Map[i][j] == 'o')G[a[i][j]].push_back(b[i][j]);
 95 }
 96 int main()
 97 {
 98
 99     cin >> T;
100     while(T--)
101     {
102         cin >> n >> m;
103         for(int i = 0; i < n; i++)cin >> Map[i];
104         build_Map();
105         printf("Case :%d\n", ++cases);
106         cout<<maxmatch()<<endl;
107     }
108     return 0;
109 }

转载于:https://www.cnblogs.com/fzl194/p/8874584.html

ZOJ-1654 Place the Robots---二分图最小点覆盖+构图相关推荐

  1. 二分图最小点覆盖构造方案+König定理证明

    原文链接 前言 博主很笨 ,如有纰漏,欢迎在评论区指出讨论. 二分图的最大匹配使用 DinicDinicDinic 算法进行实现,时间复杂度为 O(ne)O(n\sqrt{e})O(ne​),其中, ...

  2. POJ 2226 二分图最小点覆盖

    题意 传送门 POJ 2226 题解 每个泥泞地需要被至少一块横着或竖着的板子覆盖,那么预处理出不能覆盖草地的限制下,所有尽可能长的横板子与竖板子.对可覆盖同一块泥泞地的 222 块板子连边,则转化为 ...

  3. POJ - 3041 Asteroids 二分图最小点覆盖

    题目链接 二分图一个很重要的定理:看了很多大神的博客表示看不懂为什么,以后再看 最小点覆盖=最大匹配 最小点覆盖就是在二分图里边,选择一个点,将所有与该点相链接的边删去,问最小找多少个点能够把所有的边 ...

  4. hihocoder 1127 : 二分图三·二分图最小点覆盖和最大独立集

    最大独立集问题: 在图G中选取尽可能多的点,使得任意两个点之间没有连边. 结论:最大独立集的点数 = 总点数 - 二分图最大匹配 证明: 假设最大独立集的点数为|U|,二分图最大匹配的匹配数为|M|, ...

  5. hdu 1054 Strategic Game 二分图最小点覆盖

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 题意: 给出一个无向图,求最小点覆盖. 思路: 用网络流来做设立一个超级源点和一个超级汇点. 每 ...

  6. 二分图最小点覆盖König定理的简单证明

    König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选了一个点就相当于覆盖了以它为端点的所有 ...

  7. 【二分图|最小点覆盖集】König定理及其证明

    转自Matrix67 二分图最大匹配的König定理及其证明 如果你看不清楚第二个字母,下面有一个大号字体版本: 二分图最大匹配的König定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K ...

  8. 图论——二分图——最小点覆盖

    最小点集覆盖 == 最大匹配 一.什么是最小点覆盖 点覆盖的概念定义: 对于图G=(V,E)中的一个点覆盖是一个集合S⊆V使得每一条边至少有一个端点在S中. 最小点覆盖:点个数最少的S集合. 这是我个 ...

  9. [luogu3231 HNOI2013] 消毒 (二分图最小点覆盖)

    传送门 Description 最近在生物实验室工作的小T遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为abc,a.b.c 均为正整数.为了实验的方便,它被划分为abc ...

最新文章

  1. LeetCode 207. Course Schedule--有向图找环--面试算法题--DFS递归,拓扑排序迭代--Python
  2. Java Se:自定义ClassLoader
  3. 简单封装 HTTP 请求
  4. 云计算五种定义辨析[摘]
  5. ESP32移植wolfssl方法
  6. AtCoder AGC031F Walk on Graph (图论、数论)
  7. mysql端口被占用_MySQL重启端口被占用处理
  8. html 保存文件指定路径,78.上传文件及在服务器保存文件到任意路径
  9. 文献阅读 - Genome-wide consequences of deleting any single gene
  10. 天天动听 半透明Menu效果
  11. 智能计米器jk76怎么安装_春节智能锁消费指南:只看价格的后果有多严重?
  12. python编写递归函数和非递归函数、输出斐波那契数列_C语言编程:用递归和非递归法输出斐波那契数列...
  13. Angr安装与使用之使用篇(九)
  14. imo与slack竞品分析报告
  15. 【2022】软著申请流程及注意事项分享一下
  16. 如何通过拍照识别植物?试试这几个软件
  17. java ee页面间怎么传值_jsp页面间常见的几种传值方式
  18. 怎样实现url隐形转发?
  19. 维修计算机的基本操作论文,《计算机维修与处理选修论文.doc
  20. linux镜像文件没有gho,【iso文件中没有gho文件】iso变gho_iso文件里没有gho-系统城...

热门文章

  1. [Java] Hashcode的作用
  2. 局域网怎样自动安装FLASH插件(浏览器不安装flashplayer都可以浏览.swf文件)
  3. WINDOWS 2008 脱机文件夹
  4. xgboost api
  5. ssh协议是osi_TCP/IP 协议模型
  6. Python是如何一步步成为热门编程语言的?
  7. Python内置函数之输入输出函数
  8. icp mysql_MySQL · 特性分析 · Index Condition Pushdown (ICP)
  9. python语言type board_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题……...
  10. pythonscrapy爬虫_Python 爬虫:Scrapy 实例(二)