Battle shipsHDU - 5093

  题目大意:n*m的地图,*代表海洋,#代表冰山,o代表浮冰,海洋上可以放置船舰,但是每一行每一列只能有一个船舰(类似象棋的車),除非同行或者同列的船舰中间有冰山挡着,问最多能放多少个船舰?

  之前做过一个放置炮的,那时数据小直接暴力加搜索就A了,然而这题暴力搜索的话,直接了当的TLE,没办法只好去学新东西了。二分图这个概念只有在之前的题目中做过匈牙利的板子题,可是具体概念和思路并不了解,这题也正好提醒了我去深入了解。但最近需要做的事情较大,一直想整理的一些算法和模板总结也暂时拖一拖。

  回到这题,为什么可以用二分匹配做呢,首先如果没有障碍全是海的话,那就刚好是每一行每一列只能放一个,那我们分配的时候就是给每一行分配一列,这样一行一列刚好对应了放置的位置,而这个给每一行分配一列的过程刚好也可以用二分匹配实现。那么多了障碍之后,该如何处理呢,其实也就是一行分成多行,我们把相同行的统一编号化成一块区域,举个例子,比如2*6的地图

  ******

  ******

  之前每个点对行编号就是

  111111

  111111

  而多了障碍之后

  ***#**

  **#***

  这时的编号就是

  111022

  330444

  列的处理也是类似,列的编号就是

  123056

  120456

  有了编号之后,我们就可以根据共同点连边,像行编号为1的点和列编号为1,2,3的点有公共点,那么它们可以连边。上图每个行块可以连的列块就是

  1:1 2 3

  2:5,6

  3:1,2

  4:4,5,6

  这时我们就是尽可能多的给每一个行快分配一个列块,这样就可以得到最多的点,也就是最多能放置的数目。

 #include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
char s[][];
int x,y,xid[][],yid[][],cj[],vis[];
vector<int> vv[];
bool match(int u)
{
for(int i=;i<vv[u].size();i++)
{
int v=vv[u][i];
if(!vis[v])//这个列还没遍历过
{
vis[v]=;
if(!cj[v]||match(cj[v]))//这个列块还没分配给某个行块
{//或者它分配给的行块可以匹配其他列块
cj[v]=u;
return ;
}
}
}
return ;
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%s",s[i]);
memset(xid,,sizeof(xid));
memset(yid,,sizeof(yid));
x=,y=;
for(int i=;i<n;i++)
{
int j=,is=;
while(j<m)
{
if(s[i][j]=='#')
is=;
while(j<m&&s[i][j]=='#')
j++;
if(s[i][j]=='*')
{
if(!is)
x++;
is=;
xid[i][j]=x;
}
j++;
}
}//给每个行块编号
for(int i=;i<m;i++)
{
int j=,is=;
while(j<n)
{
if(s[j][i]=='#')
is=;
while(i<n&&s[j][i]=='#')
j++;
if(s[j][i]=='*')
{
if(!is)
y++;
is=;
yid[j][i]=y;
}
j++;
}
}//给每个列块编号
for(int i=;i<=x;i++)
vv[i].clear();
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(s[i][j]=='*')//二分图加边
vv[xid[i][j]].push_back(yid[i][j]);
int ans=;
memset(cj,,sizeof(cj));
for(int i=;i<=x;i++)//匈牙利算法模板
{
memset(vis,,sizeof(vis));
ans+=match(i);
}
printf("%d\n",ans);
}
return ;
}

门泊东吴万里船

  感觉二分匹配难在怎么想到这个建边

Battle ships HDU - 5093二分匹配的更多相关文章

  1. hdu 5093 二分匹配

    /* 题意:给你一些冰岛.公共海域和浮冰,冰岛可以隔开两个公共海域,浮冰无影响 求选尽可能多的选一些公共海域点每行每列仅能选一个. 限制条件:冰山可以隔开这个限制条件.即*#*可以选两个 预处理: * ...

  2. hdu 4169 二分匹配最大独立集 ***

    题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 #inclu ...

  3. hdu 4685 二分匹配+强连通分量

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 这一题是poj 1904的加强版,poj 1904王子和公主的人数是一样多的,并且给出 ...

  4. H - Prince and Princess - HDU 4685(二分匹配+强连通分量)

    题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备 ...

  5. HDU 3729 二分匹配 反向匹配

    题意: 给定 n个学生 说的 自己 考试排名的 可能范围 确定最多几个人说真话 如果有多种答案,输出字典序最大的那种( 要求字典序最大,所以solve中从最大字典序开始匹配) 思路: 题目给定  点 ...

  6. HDU -1151 二分匹配与有向无环图不相交最小路径覆盖数

    题意: 考虑一个小镇,那里的所有街道都是单向的,并且每条街道都从一个路口通往另一个路口.还众所周知,从一个十字路口开始,穿过城镇的街道,您将永远无法到达同一十字路口,即,城镇的街道没有环. 基于这些假 ...

  7. HDU 2603 二分匹配

    #include <queue>#include <vector>#include <cstdio>#include <cstring>#include ...

  8. hdu 1528 二分匹配

    #include<stdio.h> #include<string.h> int map[100][100],mark[100],link[100],max2,k; int f ...

  9. Hdu 2389 二分匹配

    题目链接 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Ja ...

随机推荐

  1. Redis分布式锁解决抢购问题

    转:https://segmentfault.com/a/1190000011421467 废话不多说,首先分享一个业务场景-抢购.一个典型的高并发问题,所需的最关键字段就是库存,在高并发的情况下每次 ...

  2. 计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践

    计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践 2018年06月13日 16:38:11 轻春 阅读数 6004更多 分类专栏: 机器学习 机器学习荐货情报局   版 ...

  3. 【spring Boot】spring boot1.5以上版本@ConfigurationProperties取消location注解后的替代方案

    前言 =========================================== 初步接触Spring Boot ===================================== ...

  4. 怎样理解 Vue 的 "Hello, World!" 代码?

    直接复制以下代码到 html 文件中即可运行. <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...

  5. python 小数精度控制

    可以用:round(数值,保留小数位数) 详情参考 https://www.cnblogs.com/herbert/p/3402245.html

  6. Winform 5种皮肤小结(内含丰富的下载实例)

    软件界面就是指软件中面向操作者而专门设计的用于操作使用及反馈信息的指令部分. 优秀的软件界面有简便易用,突出重点,容错高等特点. 1.东日IrisSkin  使用IrisSkin只能是对单一的控件重绘 ...

  7. 【原创】大叔经验分享(58)kudu写入压力大时报错

    kudu写入压力大时报错 19/05/18 16:53:12 INFO AsyncKuduClient: Invalidating location fd52e4f930bc45458a8f29ed1 ...

  8. LeetCode 腾讯精选50题--最小栈

    题目很简单,实现一个最小栈,能够以线形的时间获取栈中元素的最小值 自己的思路如下: 利用数组,以及两个变量, last用于记录栈顶元素的位置,min用于记录栈中元素的最小值: 每一次push,都比较m ...

  9. 三主机配置 keepalived VIP高可用

    三台主机: 192.168.33.134 192.168.33.136 192.168.33.137   实验前: 关闭selinux 和iptables     1). 192.168.33.134 ...

  10. 逆向破解H.Koenig 遥控器 Part 2

    逆向破解H.Koenig 遥控器 Part 2 到目前为止,我们已经知道了RF收发器的安装过程,下面是我们所掌握的东西 : l 无线电收发器是一个Avantcom A7105 l 调制是FSK l 频 ...