Description

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

Input

第一行输入两个正整数n,m,n表示地图的行数,m表示地图的列数。1≤n,m≤50。接下来输入n行m列个字符,代表网
格地图。*的个数不超过n*m个

Output

输出一个整数a,表示最多能放置炸弹的个数

Sample Input

4 4
#∗∗∗
∗#∗∗
∗∗#∗
xxx#

Sample Output

5
 
经典题了,遇到#号把行列拆开然后二分图匹配。
粘错模板WA了一发QAQ。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
const int maxn=3010;
const int maxm=50010;
const int inf=1e9;
struct ISAP{
struct tedge{int x,y,w,next;}adj[maxm];int ms,fch[maxn];
int d[maxn],s[maxn],cur[maxn],gap[maxn],n,top;
void init(){
ms=0;top=0;
memset(d,-1,sizeof(d));
memset(fch,-1,sizeof(fch));
}
void AddEdge(int u,int v,int w){
adj[ms]=(tedge){u,v,w,fch[u]};fch[u]=ms++;
adj[ms]=(tedge){v,u,0,fch[v]};fch[v]=ms++;
}
void bfs(){
queue<int>Q;Q.push(n);d[n]=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=fch[u];i!=-1;i=adj[i].next){
int v=adj[i].y;
if(d[v]==-1) d[v]=d[u]+1,Q.push(v);
}
}
}
int solve(int S,int T){
n=T;bfs();int k=S,i,flow=0;
for(i=0;i<=n;i++) cur[i]=fch[i],gap[d[i]]++;
while(d[S]<n){
if(k==n){
int mi=inf,pos;
for(i=0;i<top;i++) if(adj[s[i]].w<mi) mi=adj[s[i]].w,pos=i;
for(i=0;i<top;i++) adj[s[i]].w-=mi,adj[s[i]^1].w+=mi;
flow+=mi;top=pos;k=adj[s[top]].x;
}
for(i=cur[k];i!=-1;i=adj[i].next){
int v=adj[i].y;
if(adj[i].w&&d[k]==d[v]+1){cur[k]=i;k=v;s[top++]=i;break;}
}
if(i==-1){
int lim=n;
for(i=fch[k];i!=-1;i=adj[i].next){
int v=adj[i].y;
if(adj[i].w&&d[v]<lim) lim=d[v],cur[k]=i;
} if(--gap[d[k]]==0) break;
d[k]=lim+1;gap[d[k]]++;
if(k!=S) k=adj[s[--top]].x;
}
} return flow;
}
}sol;
char Map[55][55];
int n,m,S,T,A[55][55],B[55][55];
int main() {
scanf("%d%d",&n,&m);
rep(i,1,n) scanf("%s",Map[i]+1);sol.init();
rep(i,1,n) {
S++;
rep(j,1,m) {
if(Map[i][j]=='#') S++;
A[i][j]=S;
}
}
rep(j,1,m) {
S++;
rep(i,1,n) {
if(Map[i][j]=='#') S++;
B[i][j]=S;
}
}
S++;T=S+1;sol.n=T;
rep(i,1,A[n][m]) sol.AddEdge(S,i,1);
rep(i,A[n][m]+1,B[n][m]) sol.AddEdge(i,T,1);
rep(i,1,n) rep(j,1,m) if(Map[i][j]=='*') sol.AddEdge(A[i][j],B[i][j],1);
printf("%d\n",sol.solve(S,T));
return 0;
}

  

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]游戏

    原题链接 Description 给出一个的地图,地图上有空地.软石头和硬石头.求在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到.炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威 ...

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

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

  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. css 全局 兼容性问题

    css 笔记 第一种:常用的全局CSS属性设置 //参考大型网站,如凤凰网 (1)清除所有的标记的内外边距 body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,p ...

  2. C# 重绘tabControl,添加关闭按钮(续)

    在上一篇随笔中,添加关闭按钮是可以实现 ,但细心一点就会发现,每次关闭一个选项卡,tableControl都会自动跳到第一个页面,显然 这不是我们想要的,为此,我修改了部分的代码.除此之外,我还添加了 ...

  3. 面试题之【打印1到最大的N位数】

    题目描述:给定一个数字N,打印从1到最大的N位数. 看起来像是很简单的问题(虽然实际也不是很难...)我们很容易写出这样的代码: #include<iostream> #include&l ...

  4. GitHub 使用教程图文详解(转)

    大纲: 一.前言 二.GitHub简介 三.注册GitHub账号 四.配置GitHub 五.使用GitHub 六.参与GitHub中其它开源项目 七.总结 注,GitHub官网:https://git ...

  5. ViewPager onPageChangeListener总结(转)

    android ViewPager滑动事件讲解 今天在做项目的时候,由于要处理viewPager页面滑动的事件,所以对其进行了一个小小的研究: 首先ViewPager在处理滑动事件的时候要用到OnPa ...

  6. 利用opencv进行相机标定程序

    #include "Stafx.h" ; //棋盘上有13个格子,那么角点的数目12 ; ; //图片的总张数 int main(int argc, char** argv) { ...

  7. Fragment 操作原理

      fragment 本质 fragment 本质上是 view 的容器和控制器,fragment 是 activity 的碎片. activity 是什么呢?activity 是四大组件之一,因为 ...

  8. pig的各种运行模式与运行方式详解

    一.pig的运行模式: Pig 有两种运行模式: Local 模式和 MapReduce 模式.当 Pig 在 Local 模式运行的时候, Pig 将只访问本地一台主机:当 Pig 在 MapRed ...

  9. 【MySQL 安装过程1】顺利安装MySQL完整过程

    一.MySQL Sever的安装 1.开始安装: 2.这里就要开始注意,端口号我们的my SQL端口号为3306 3.下面要输入用户名和用户密码.注意,帐号密码  都是 root. 4.下面的最后一页 ...

  10. DSP using MATLAB 示例Example2.11

    上代码: b = [1]; a = [1, -1, 0.9]; n = [-20:120]; h = impz(b,a,n); set(gcf,'Color','white'); %subplot(2 ...