原题链接

Description

给出一个n×m(n,m≤50)的地图,地图上有空地、软石头和硬石头。求在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透任意个软石头,但是不能穿透硬石头。

Solution

把每行/每列以硬石头为界划分成若干个部分,如图:



则每个空地都是一个横着的部分和一个竖着的部分的交,每个部分里最多只能有一个炸弹。

于是把每个部分看成图中的一个顶点;若两个部分交于一块空地则连一条边。显然这是一个二分图,因为竖着的部分之间不会有边,横着的部分之间也不会有边。该图中的一组匹配就表示放了一个炸弹在这两个部分的交上,那么答案就是这个二分图的最大匹配数。

最多划分为nm个部分,这些部分之间最多有nm条边。时间复杂度为O(n2m2)。

Code

//[Tjoi2016&Heoi2016]游戏
#include <cstdio>
#include <cstring>
int const N=3e3;
int n,m; char map[N][N];
int cnt,row[N][N],col[N][N];
bool ed[N][N];
int link[N]; bool used[N];
bool match(int u)
{
for(int v=1;v<=cnt;v++)
if(ed[u][v]&&!used[v])
{
used[v]=true;
if(!link[v]||match(link[v])) {link[v]=u; return true;}
}
return false;
}
int Hungary()
{
int res=0;
for(int i=1;i<=cnt;i++)
{
memset(used,0,sizeof used);
if(match(i)) res++;
}
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",map[i]+1);
for(int i=1;i<=n;i++)
for(int j1=1;j1<=m;j1++)
{
if(map[i][j1]=='#'||row[i][j1]) continue;
cnt++;
for(int j2=j1;j2<=m&&map[i][j2]!='#';j2++) row[i][j2]=cnt;
}
for(int j=1;j<=m;j++)
for(int i1=1;i1<=n;i1++)
{
if(map[i1][j]=='#'||col[i1][j]) continue;
cnt++;
for(int i2=i1;i2<=n&&map[i2][j]!='#';i2++) col[i2][j]=cnt;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(map[i][j]=='*') ed[row[i][j]][col[i][j]]=true;
printf("%d\n",Hungary());
return 0;
}

P.S.

HDU1045是这道题的简化版。

BZOJ4554 - [TJOI2016&HEOI2016]游戏的更多相关文章

  1. [BZOJ4554][TJOI2016&&HEOI2016]游戏(匈牙利)

    4554: [Tjoi2016&Heoi2016]游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 857  Solved: 506[Sub ...

  2. bzoj4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

    4554: [Tjoi2016&Heoi2016]游戏 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能 ...

  3. bzoj4554: [Tjoi2016&Heoi2016]游戏(二分图匹配)

    4554: [Tjoi2016&Heoi2016]游戏 题目:传送门 题解: 一道很牛逼的匈牙利..和之前模拟赛的一道题有点相似(不过这题不用完美匹配) 我们可以把连续的行和列全部编号(如果之 ...

  4. BZOJ4554: [Tjoi2016&Heoi2016]游戏

    Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了这样一 ...

  5. BZOJ4554: [Tjoi2016&Heoi2016]游戏 luoguP2825 loj2057

    题面描述:尽可能多的放置符合要求的炸弹. 分析: 在i,j处放置炸弹,则在第i行,上一个硬石头之后,下一个硬石头之前,第j列,上一个硬石头之后,下一个硬石头之前,不能再次放置炸弹. 首先,这个题,一看 ...

  6. 【BZOJ4554】[Tjoi2016&Heoi2016]游戏 二分图最大匹配

    [BZOJ4554][Tjoi2016&Heoi2016]游戏 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 ...

  7. BZOJ_4554_[Tjoi2016&Heoi2016]游戏_二分图匹配

    BZOJ_4554_[Tjoi2016&Heoi2016]游戏_二分图匹配 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若 ...

  8. BZOJ 4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

    4554: [Tjoi2016&Heoi2016]游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4554 Descripti ...

  9. 【bzoj4554】[Tjoi2016&Heoi2016]游戏

    现在问题有硬石头和软石头的限制 所以要对地图进行预处理 分行做,把有#隔开的*(x)形成联通块的存储下来. 分列作,把有#隔开的*(x)形成联通块的存储下来. 求出所有的行联通个数和列联通个数 作为二 ...

随机推荐

  1. Linux或Window是修改snmp的默认端口

    SNMP默认端口通讯使用 UDP 161,在安装一些监控软件的过程中,常常提示端口被占用等情况,下面说一下如何修改系统的默认SNMP端口 windows修改snmp端口 1 打开services文件 ...

  2. Linux安装ffmpeg

      1.安装ffmpeg 简单步骤: A.首先去官网下载源码包,我的是ffmpeg-3.4.tar.bz2,下载之后上传至Linux准备安装,首先解压安装包: tar -xjvf ffmpeg-3.4 ...

  3. MySQL查看和修改表的存储引擎

    1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from db_name where name='table_na ...

  4. __call PHP伪重载方法

    为了避免当调用的方法不存在时产生错误,可以使用 __call() 方法来避免.该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去 该方法有两个参数,第一个参数 $function_name 会 ...

  5. Java并发系列[3]----AbstractQueuedSynchronizer源码分析之共享模式

    通过上一篇的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取.在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快 ...

  6. Notepad++ 运行java(转)

    Notepad++ 运行java java, 2013/05/04, 9 replies, 6,007 views 文章目录 Notepad++ for java 安装必须的程序 配置NppExec ...

  7. Win和Linux查看端口和杀死进程

    title: Win和Linux查看端口和杀死进程 date: 2017-7-30 tags: null categories: Linux --- 本文介绍Windows和Linux下查看端口和杀死 ...

  8. sizeof和strlen的使用

    sizeof和strlen的使用 1. sizeof 其值在编译时就计算好了,所以不能用来返回动态分配的内存空姐的大小. 当参数为下面内容是,所表达的含义: 数组——编译时分配的数组空间大小: 指针— ...

  9. 布隆过滤器(Bloom Filter)详解

    直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...

  10. DNA序列局部比对(Smith–Waterman algorithm)

    生物信息原理作业第三弹:DNA序列局部比对,利用Smith–Waterman算法,python3.6代码实现. 实例以及原理均来自https://en.wikipedia.org/wiki/Smith ...