HDU 5093 Battle ships(二分图最大匹配)
题意:一个m行n列的图由#、*、o三种符号组成,分别代表冰山、海域、浮冰,问最多可放的炮舰数(要求满足以下条件)
1、炮舰只可放在海域处
2、两个炮舰不能放在同一行或同一列(除非中间隔着一个或多个冰山)
分析:
1、如果单纯只考虑不能放在同一行同一列,那就是行号与列号的匹配,原理与UVALive 6811 Irrigation Line(二分图最小点覆盖--匈牙利算法)相同。
2、但现在隔着冰山可以放置炮舰,那假设某一行被冰山分隔成两部分,这一行的前半部分和后半部分可以看做是两行,再应用“行号”与“列号”的匹配的原理
3、既然要行号与列号匹配,那就要分别按照行和列给图标号
举例如下:
(1)若按行,则将海域从1开始标号,如果是连续的海域那标号相同,若有冰山分隔,标号加1.
PS:例如第三行22#3,此处2是形式意义上的第二行,因为有上述放置炮舰的原则,可以理解为是可以放置炮舰的第2行,而由于有冰山分隔,所以这一行的前后互不干扰,因此3可以理解为是可以放置炮舰的第3行
(2)按列同理
4、理论上讲海域可以放置炮舰,也就是说,有标号的地方可以放置炮舰,每一个放置的地方都是一个行号与列号的匹配,由此可得如下匹配
5、一条连线代表一个可放置的炮舰,求最大匹配即可
#include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<stack> #include<deque> #include<queue> #include<list> #define Min(a, b) a < b ? a : b #define Max(a, b) a < b ? b : a typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = {0, 0, -1, 1}; const int dc[] = {-1, 1, 0, 0}; const double pi = acos(-1.0); const double eps = 1e-8; const int MAXN = 50 + 10; const int MAXT = 2500 + 10; using namespace std; char a[MAXN][MAXN]; int x[MAXN][MAXN]; int y[MAXN][MAXN]; int mp[MAXT][MAXT]; bool used[MAXT]; int match[MAXT]; int m, n, cnt1, cnt2; void deal_row(){cnt1 = 1;for(int i = 0; i < m; ++i){bool flag = false;for(int j = 0; j < n; ++j){if(a[i][j] == '*'){x[i][j] = cnt1;flag = true;}if(a[i][j] == '#'){++cnt1;flag = false;}}if(flag) ++cnt1;} } void deal_column(){cnt2 = 1;for(int i = 0; i < n; ++i){bool flag = false;for(int j = 0; j < m; ++j){if(a[j][i] == '*'){y[j][i] = cnt2;flag = true;}if(a[j][i] == '#'){++cnt2;flag = false;}}if(flag) ++cnt2;} } bool Find(int x){for(int i = 1; i < cnt2; ++i){if(mp[x][i] && !used[i]){used[i] = true;if(!match[i] || Find(match[i])){match[i] = x;return true;}}}return false; } void solve(){int cnt = 0;for(int i = 1; i < cnt1; ++i){memset(used, false, sizeof used);if(Find(i)) ++cnt;}printf("%d\n", cnt); } int main(){int T;scanf("%d", &T);while(T--){memset(a, 0, sizeof a);memset(x, 0, sizeof x);memset(y, 0, sizeof y);memset(mp, 0, sizeof mp);memset(match, 0, sizeof match);scanf("%d%d", &m, &n);for(int i = 0; i < m; ++i)scanf("%s", a[i]);deal_row();deal_column();for(int i = 0; i < m; ++i){for(int j = 0; j < n; ++j){if(a[i][j] == '*'){mp[x[i][j]][y[i][j]] = 1;}}}solve();}return 0; }
转载于:https://www.cnblogs.com/tyty-Somnuspoppy/p/6036855.html
HDU 5093 Battle ships(二分图最大匹配)相关推荐
- HDU 1281 棋盘游戏 【二分图最大匹配】
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1281 题意概括: 有N*M大的棋盘,要在里面放尽量多的"车",求最多能放的车的个数, ...
- 解题报告 (九) 二分图最大匹配
文章目录 二分图最大匹配 解题报告 一.最大匹配模板题 HDU 1083 Courses HDU 2063 过山车 HDU 1528 Card Game Cheater HDU 1179 Olliva ...
- HDU 3729 I'm Telling the Truth(二分图最大匹配)
HDU 3729 I'm Telling the Truth(二分图最大匹配) http://acm.hdu.edu.cn/showproblem.php?pid=3729 题意: 一位老师想问N位同 ...
- HDU - 1054 Strategic Game(最小点覆盖-二分图最大匹配)
题目链接:点击查看 题目大意:给出一棵树,现在要在节点上放置士兵,每个士兵可以监视与其所在的节点直接相连的节点,问最少需要多少个士兵才能将整棵树都监视到 题目分析:求最少的节点,以保证每条边都有一个端 ...
- HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)
题目链接:点击查看 题目大意:给出n个人和m个雨伞,t分钟后就要下雨了,现在给出每个人的坐标和速度,以及雨伞所在的坐标,每个雨伞只能容纳一个人,题目问最多有多少个人能不被淋到 题目分析:二分图最大匹配 ...
- HDU - 1528 Card Game Cheater(二分图最大匹配)
题目链接:点击查看 题目大意:题意有点像求田忌赛马的最优解,大概意思就是现在有两个人,每个人都有n张不同的扑克牌,扑克牌的大小首先以点数来确定,点数相同的情况下以花色来决定,红桃(Heart)> ...
- HDU - 1150 Machine Schedule(最小点覆盖-二分图最大匹配)
题目链接:点击查看 题目大意:现在有一个机器A和一个机器B,A机器有n种模式,B机器有m种模式,现在有k次工作需要完成,每次工作的信息为: id x y:编号为id,在A机器要用x模式完成,在B机器要 ...
- HDU - 5090 Game with Pearls(二分图最大匹配)
题目链接:点击查看 题目大意:杰瑞和汤姆在玩游戏,游戏规则是:汤姆会拿来N个容器,每个容器内一开始就会包含1~N个小球,现在轮到杰瑞操作了,杰瑞可以选择往每个容器里加入0个或者任意k的倍数个小球,问杰 ...
- HDU - 2063 过山车(二分图最大匹配)
题目链接:点击查看 题目大意:中文题目,不多赘述 题目分析:二分图最大匹配问题,匈牙利经典算法模板题,感觉这个博客写的很好,插个眼: https://article.itxueyuan.com/Aea ...
最新文章
- SVN如何将版本库url访问地址中的https改为http
- Java基于自定义注解的面向切面的实现
- 浅谈Linux中ldconfig和ldd的用法
- python如何输出百分比的数字_Python如何输出百分比
- Android自定义组合控件--EditText和Button组合成带有清空EditText内容功能的复合控件
- 信用卡多还钱了怎么办?
- 三维旋转四元数系列(3.四元数定义与基本性质)
- Java中含有泛型的 JSON 反序列化问题
- Android开发笔记(一百三十一)水波图形与水波动画
- 小米pro笔记本2017款BIOS降级0603
- Visual Studio 2022安装时Visual Studio Installer稍等片刻...正在提取文件 进度条不动 0B每秒-已解决
- 计算机组成原理补码减法,补码加减法运算(计算机组成原理).ppt
- apache mediawiki 安装_mediawiki安装使用
- 0x0000007b电脑蓝屏的解决方法
- 力扣---LeetCode20. 有效的括号(栈)
- 《论语》原文及其全文翻译 学而篇1
- 淘宝放大镜插件(vue-piczoom)
- Java取数的整数及小数部分
- 致远OA wpsAssistServlet 任意文件上传漏洞 漏洞复现
- linux实验实训报告,linux实验实训报告.doc
热门文章
- Struts2 之配置文件编写,动作类(01)
- 美通社祝各位端午安康!
- MyBatisPlus学习笔记【part2】
- NFT 2.0:创新潜力与投资指南
- 老电脑玩游戏又卡又慢,怎么办?
- 天明创新受邀出席华为全联接大会,通过AI科技实现尘肺病的预防性筛查
- 企业员工情绪分析,帮助你解决员工情绪问题
- 讲述我一段自己打游戏的感受
- C# 打开文件夹FolderBrowserDialog与打开文件OpenFileDialog浅析
- 详解git pull命令和使用过程中遇到的常见问题:fatal: ‘origin‘ does not appear to be a git repository