Description:

在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张nm的网格地图:其中代表空地,炸弹的威力可以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸弹的威力是不能穿透的,不能在此放置炸弹。例如:给出14的网格地图xx,这个地图上最多只能放置一个炸弹。给出另一个14的网格地图x#,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最多能放置多少炸弹。

Hint:

\(n,m \le 50\)

Solution:

考虑怎么处理硬石头,其实很简单,把原图的行列拆成很多连续子串作为新的行列,这样就可以直接跑二分图行列模型了

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e5+5,inf=1e9;
int n,m,S,T,cnt,tot,ans,id1[55][55],id2[55][55],hd[mxn],cur[mxn],dep[mxn];
char a[55][55]; inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;} struct ed {
int to,nxt,w;
}t[mxn<<1]; inline void add(int u,int v,int w) {
t[cnt]=(ed) {v,hd[u],w}; hd[u]=cnt++;
t[cnt]=(ed) {u,hd[v],0}; hd[v]=cnt++;
} int bfs() {
memset(dep,0,sizeof(dep));
queue<int > q; dep[S]=1;
q.push(S);
for(int i=0;i<=T;++i) cur[i]=hd[i];
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=hd[u];i!=-1;i=t[i].nxt) {
int v=t[i].to;
if(t[i].w>0&&!dep[v])
dep[v]=dep[u]+1,q.push(v);
}
}
return dep[T];
} int dfs(int u,int f) {
if(u==T) return f;
for(int &i=cur[u];i!=-1;i=t[i].nxt) {
int v=t[i].to;
if(t[i].w>0&&dep[v]==dep[u]+1) {
int tp=dfs(v,min(t[i].w,f));
if(tp>0) {
t[i].w-=tp;
t[i^1].w+=tp;
return tp;
}
}
}
return 0;
} void Dinic() {
while(bfs())
while(int tp=dfs(S,inf))
ans+=tp;
} int get(int x,int y) {
return (x-1)*m+y;
} int main()
{
n=read(); m=read(); T=n*m+n*m+1; memset(hd,-1,sizeof(hd));
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin>>a[i][j];
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j) {
if(a[i][j]=='#') continue ;
if(j==1||a[i][j-1]=='#') ++tot,add(S,tot,1);
id1[i][j]=tot;
}
for(int j=1;j<=m;++j)
for(int i=1;i<=n;++i) {
if(a[i][j]=='#') continue ;
if(i==1||a[i-1][j]=='#') ++tot,add(tot,T,1);
id2[i][j]=tot;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j) {
if(a[i][j]!='*') continue ;
add(id1[i][j],id2[i][j],1);
}
Dinic(); printf("%d",ans);
return 0;
}

[HEOI2016/TJOI2016]游戏的更多相关文章

  1. [ZJOI2007]矩阵游戏【bzoj1059/洛谷1129】/ [HEOI2016/TJOI2016]游戏

    小QQ是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N \times NN×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种 ...

  2. [HEOI2016/TJOI2016]游戏 解题报告

    [HEOI2016/TJOI2016]游戏 看起来就是个二分图匹配啊 最大化匹配是在最大化边数,那么一条边就代表选中一个坐标内的点 但是每一行不一定只会有一个匹配 于是把点拆开,按照'#'划分一下就好 ...

  3. [luogu2825 HEOI2016/TJOI2016] 游戏 (二分图最大匹配)

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

  4. 【[HEOI2016/TJOI2016]游戏】

    据说是网络流棋盘模型了 我们把每一个连续子段都看成一个点,我们先把所有的行上的连续子段找出来给他们编上号,所有列上的连续子段找出来也编上号 现在每个格子都有两个编号了,\(a[i][j]\)表示行所对 ...

  5. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

  6. [HEOI2016/TJOI2016]树

    [HEOI2016/TJOI2016]树 思路 做的时候也是糊里糊涂的 就是求最大值的线段树 错误 线段树写错了 #include <bits/stdc++.h> #define FOR( ...

  7. 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告

    P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...

  8. 【LG4091】[HEOI2016/TJOI2016]求和

    [LG4091][HEOI2016/TJOI2016]求和 题面 要你求: \[ \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*j! \] 其中\(S\)表示第二类斯特林数,\ ...

  9. 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告

    P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...

随机推荐

  1. 如何在sublime安装ctags函数追踪插件

    一.这个插件是需要下载执行软件才能够操作的,下载地址http://prdownloads.sourceforge.net/ctags/ctags58.zip 然后解压到自己喜欢的目录下,我是安装到 D ...

  2. react 常见api 使用(长期更新)

    1.父子通信 1.1 父-子 props 父组件: class myPage extends React.Component { render() { return ( <div> {/* ...

  3. Springboot+Mybaits之两张表同时插入数据

    项目需求是,一张表添加数据的同时,另外一张表也需要添加数据,话不多说,直接上代码. 1.Controller,我把两个DTO直接放到一个@RequestBody中.其中throws是后台获取当前时间抛 ...

  4. 从头开始学gradle【Gradle 构建基础】

    构建基础 Project 和 task:projects 和 tasks是 Gradle 中最重要的两个概念. 任何一个 Gradle 构建都是由一个或多个 projects 组成.每个 projec ...

  5. 搭建Linux运行环境-虚拟机

    1.虚拟机软件介绍 虚拟机(Virtual Machina)软件就是一套特殊的软件,它可以作为系统独立运行,也可以运行与系统之上. 若是运行与系统之上的虚拟机软件,在一台电脑(PC或笔记本等)上安装虚 ...

  6. jquery +ajax 上传加预览

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. 生活英语读写MOOC-Literature Tutor-有声名著阅读推荐

    生活英语读写MOOC-Literature Tutor-有声名著阅读推荐 1. Alice's Adventures in Wonderland 爱丽丝漫游奇境记 音频与文本下载地址:链接:http: ...

  8. Lesson 3-2 语句:循环语句

    3.2 循环语句 3.2.1 while 循环语句 --- while 语句包含:关键字while.条件.冒号.while子句(代码块). --- 执行while 循环,首先判断条件是否为真,如果为假 ...

  9. netstat、ps、top 、kill 命令备忘

    1.ps命令用于显示当前进程 (process) 的状态. -aux 显示所有包含其他使用者的行程. -e 显示所有进程. -f 全格式输出. 一般带参数 -ef 或者 -aux ,差别不大. 区别: ...

  10. 马拉车算法——求回文串起点hdu3294

    #include<bits/stdc++.h> using namespace std; #define maxn 500005 int p[maxn]; ]; int start; in ...