hdu 5093 Battle ships 匈牙利 很巧妙的建图思路
//这题逼我把匈牙利学了 之前一直很勤快敲网络流 而且不以为耻反以为荣
解:首先按行扫描编号,如果在同一块中(即可以相互攻击),那么将其标为相同的数组,对列也做同样的操作。
然后扫描整张图,如果行编号为a的块与列编号为b的块有公共点,那么将二部图中A集合中a点与B集合中b点相连。最后求出来最大二分匹配数就是答案。
(为什么这样做)首先很明显的,二部图中每一条边就对应原图中的一个点,因此,匹配数=边数=最多可放置的战舰数,另外二分图每个点只能匹配一次,对应到原题中就是每一块只能放置一个战舰.
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<string> using namespace std; const int INF=; int T;
int n,m,num_a,num_b;
char c[][];
int a[][];
int b[][];
bool adj[];
int link[];
int f[][];
bool used[]; bool work(int x){
for (int i=;i<=num_b;i++){
if (f[x][i] && !adj[i]){
adj[i]=;
if (!used[i] || work(link[i])){
link[i]=x;
used[i]=;
return true;
}
}
}
return false;
} int main(){
scanf("%d",&T);
for (int cas=;cas<=T;cas++){
scanf("%d%d",&n,&m);
for (int i=;i<n;i++) scanf("%s",c[i]);
memset(a,,sizeof(a));
memset(b,,sizeof(b));
int t=;
bool flag=;
for (int i=;i<n;i++){
if (flag){
t++;
flag=false;
}
for (int j=;j<m;j++){
if (c[i][j]=='*') {
a[i][j]=t;
flag=true;
}
if (flag && c[i][j]=='#'){
flag=false;
t++;
}
}
}
if (flag) t++;
num_a=t-;
t=;
flag=;
for (int j=;j<m;j++){
if (flag){
t++;
flag=false;
}
for (int i=;i<n;i++){
if (c[i][j]=='*') {
b[i][j]=t;
flag=true;
}
if (flag && c[i][j]=='#'){
flag=false;
t++;
}
}
}
if (flag) t++;
num_b=t-;
memset(used,,sizeof(used));
memset(f,,sizeof(f));
memset(link,,sizeof(link));
for (int i=;i<n;i++){
for (int j=;j<m;j++){
if (a[i][j]!= && b[i][j]!=){
f[a[i][j]][b[i][j]]=;
}
}
}
int ans=;
for (int i=;i<=num_a;i++){
memset(adj,,sizeof(adj));
if (work(i)) ans++;
}
printf("%d\n",ans);
}
return ;
}
/*
2
4 4
*ooo
o###
**#*
ooo*
4 4
#***
*#**
**#*
ooo#
*/
hdu 5093 Battle ships 匈牙利 很巧妙的建图思路的更多相关文章
- HDU 5093 Battle ships(二分图最大匹配)
题意:一个m行n列的图由#.*.o三种符号组成,分别代表冰山.海域.浮冰,问最多可放的炮舰数(要求满足以下条件) 1.炮舰只可放在海域处 2.两个炮舰不能放在同一行或同一列(除非中间隔着一个或多个冰山 ...
- hdu 5093 Battle ships
二分图匹配 #include<cstdio> #include<cstring> #include<iostream> #include<cmath> ...
- hdu 5093 Battle ships (二分图)
二分图最大匹配问题 遇到冰山就把行列拆成两个部分.每个部分x也好,y也好只能匹配一次 图画得比较草,将就着看 横着扫一遍,竖着扫一遍,得到编号 一个位置就对应一个(xi,yi)就是X集到Y集的一条边, ...
- hdu 5093 Battle ships(二分图最大匹配)
题意: M*N的矩阵,每个格子上是三个之一:*.o.#. (1 <= m, n <= 50) *:海洋,战船可以停在上面. o:浮冰,战船 ...
- hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图
题目分析: 一个人要不是爱狗讨厌猫的人,要不就是爱猫讨厌狗的人.一个人喜欢的动物如果离开,那么他也将离开.问最多留下多少人. 思路: 爱猫和爱狗的人是两个独立的集合.若两个人喜欢和讨厌的动物是一样的, ...
- hdoj 5093 Battle ships 【二分图最大匹配】
题目:pid=5093" target="_blank">hdoj 5093 Battle ships 题意:给你一个n*m的图,图中有冰山 '# ',浮冰 'o' ...
- hdu 2732 Leapin' Lizards 最大流 拆点 建图
题目链接 题意 给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴. 每个柱子只能承受有限只蜥蜴从上面经过.每只蜥蜴每次能走到相距曼哈顿距离\(\leq k\)的格子中去. 问有多少只蜥蜴能走出网 ...
- HDOJ 5093 Battle ships 二分图匹配
二分图匹配: 分别按行和列把图展开.hungary二分图匹配. ... 例子: 4 4 *ooo o### **#* ooo* 按行展开. .. . *ooo o#oo oo#o ooo# **#o ...
- hdu 4185 Oil Skimming(二分图匹配 经典建图+匈牙利模板)
Problem Description Thanks to a certain "green" resources company, there is a new profitab ...
随机推荐
- ffmpeg参数解释 <第三篇>
例子:ffmpeg -y -i "1.avi" -title "Test" -vcodec xvid -s 368x208 -r 29.97 -b 1500 - ...
- C# Process类_进程_应用程序域与上下文之间的关系
进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源.进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非分布式),一个进程运行的失败也不会影响其他 ...
- ArcGIS 栅格数据已加载后的获取
原文 http://www.cnblogs.com/zoe-j/archive/2012/02/16/2354037.html 简单记一下,最近开始做Arcgis engine的开发, 已经通过了to ...
- TCP Keepalive HOWTO
TCP Keepalive HOWTO Fabio Busatto <fabio.busatto@sikurezza.org> 2007-05-04 Revision History Re ...
- java中spring提供的属性copy方法
BeanUtils.copyProperties(source, target); 今天用到属性的copy方法
- json中换行问题
json中不能存在换行,但可以进行替换后给服务器 function(text_info) { text_info=text_info.replace(/\r/gm,"<br\>& ...
- App开发革命进阶路
APP开发的成败,或许不是程序编辑的多么完美,界面设计的多么精致,其实这就是一场用户体验的革命. APP的使用场景是移动设备,人机交互以单指手“触点”为主,大段文字输入是交互的禁区.因此,APP带来了 ...
- 网站SEO优化中内部链接的优化
重要性:内链有效的优化能够间接的提高某页面的权重达到搜索排名靠前的效果.同时有效的带领搜索引擎蜘蛛对整站进行抓取. 网站头部导航: 这个导航称为'网站主导航',当用户来到网站需要给他们看到的内容.也就 ...
- Python 自动化脚本学习(二)
流程控制 布尔值 temp = True temp = False 比较符号 == != < <= > >= 与或非 and or not 混合布尔的比较 (4<5)an ...
- Spring(三)——AOP
AOP全名为Aspect-Oriented Programming,意思是面向横切面编程,前边我们有过介绍 面向横切面编程AOP的理解 ,我们通过这种编程思想很容易的扩展我们的应用程序. 一,如何 ...