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. 深入web的请求过程

    一.深入web的请求过程 1.1.B/S网络架构概述 · 从前端到后端,都基于应用层协议HTTP来交互数据.一个请求就对应了一个操作,完成操作之后就断开了连接.基于这样的特点可以用来满足海量的用户的操 ...

  2. npm 如何安装npm包

    1.每个插件或者组件都会在官方网站有教程. 以https://v4.bootcss.com 为例 2.vuetify的 3.moment 的库

  3. stat 文件三个时间点

    Linux文件3个时间点(access time,modify time,change time) access time:表示最后一次访问(仅仅是访问,没有改动)文件的时间. 注意:至于为什么会出现 ...

  4. 【easy】479. Largest Palindrome Product

    Find the largest palindrome made from the product of two n-digit numbers Since the result could be v ...

  5. QT windeployqt

    qt发布release版本时需要打包一些dll,需要哪些呢?请看截图: 在qt的安装包下找到这些文件,放在release文件夹下即可,当然有些时候也会需要一些其他的,比如含有串口的程序还需要加入Qt5 ...

  6. Uncaught TypeError: Cannot read property ‘split’ of undefined

    问题 :Uncaught TypeError: Cannot read property ‘split’ of undefinedat HTMLLIElement. split()切割的问题 因为遍历 ...

  7. deepin(debian)下使用Git

    Github github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开. 安装git 安装 sudo apt-get install g ...

  8. luoguP1941-

    飞扬的小鸟 20分&50分: #include<iostream> #include<cstdio> #include<cstring> #include& ...

  9. 2018年最新JAVA面试题总结之基础(1)

    转自于:https://zhuanlan.zhihu.com/p/39322967 1.JAVA中能创建volatile数组吗?volatile能使得一个非原子操作变成原子操作吗? 回答: 能,Jav ...

  10. OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测

    一.Harris角点检测 原理: 角点特性:向任何方向移动变换都很大. Chris_Harris 和 Mike_Stephens 早在 1988 年的文章<A CombinedCorner an ...