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. [LeetCode] Remove Element (三种解法)

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  2. freemarker 实现对URL的安全编码

    [#setting url_escaping_charset='utf-8'] ${yourstr?url}

  3. fis3-postpackager-loader插件说明

    fis3-postpackager-loader 静态资源前端加载器,用来分析页面中使用的和依赖的资源(js或css), 并将这些资源做一定的优化后插入页面中.如把零散的文件合并. 注意 此插件做前端 ...

  4. TCP 连接中断的判断

    关于TCP 3次握手,4次分手就不多说了.如何判断TCP连接是否中断是个大问题. 1 TCPKeep-alive 机制 并不是TCP 规范的一部分,实现细节差距大. 2 使用heartbeat 检测 ...

  5. 1-01Sql Sever 2008的安装

    Sql Sever 2008对计算机的配置要求: 1:处理器:最低1.4Ghz的处理器,建议使用2.0GHz或更高的处理器  . 2:内存:最小512MB, 建议使用1GB或更高的处理器. 3:磁盘容 ...

  6. [Mobile] 手机浏览器输入框-数字输入框

    手机浏览器的输入框,一直都是以web的方式进行开发的,没有关注到用户体验,领导提出了输入框要弹出数字输入框,想来应该有这种技术能实现.   搜索之后发现可以使用type="number&qu ...

  7. 通过Small Basic把儿子/女儿带入编程的世界

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:今天是儿子3岁的生日,就来介绍一下适合给儿童培养兴趣的编程语言--微软Small Ba ...

  8. ASSM 的三级位图结构

    自动段空间管理(ASSM),它首次出现在Oracle920里(在920以前,段空间的管理方式叫做MSSM,它是由连接列表freelist来完成的,因为freelist存在串行的问题,因此容易引起段头的 ...

  9. Codeforces Testing Round #12 C. Subsequences 树状数组

    C. Subsequences     For the given sequence with n different elements find the number of increasing s ...

  10. java Iterator Fail-fast机制

    Fail-fast:在迭代的过程中发现数据被改变时立即抛出异常,而不是等遍历完了再抛出异常:可以理解为快速感知. 在并发的时候,当线程A正遍历一个Collection或Map,这时另外一个线程B修改C ...