[HNOI2007]紧急疏散evacuate

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3626  Solved: 1059
[Submit][Status][Discuss]

Description

发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一
块空地;如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以从这儿撤出房间。已知门
一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都
可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是
说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的
位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本
不可能。

Input

第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,
以下N行M列描述一个N M的矩阵。其中的元素可为字符'.'、'X'和'D',且字符间无空格。

Output

只有一个整数K,表示让所有人安全撤离的最短时间,
如果不可能撤离,那么输出'impossible'(不包括引号)。

Sample Input

5 5
XXXXX
X...D
XX.XX
X..XX
XXDXX

Sample Output

3

HINT

2015.1.12新加数据一组,鸣谢1756500824

题解:二分+二分图匹配吧,网络流可以,需要注意一下,一个时刻只能允许出去一个人,所以出口再裂几个点即可。

 #include<cstdio>
const int M=,inf=0x3f3f3f3f;
int h[M],q[M],S,T;
int es[M],enx[M],ev[M],e0[M],ep=;
int n,m;
char s[][];
bool bfs(){
int ql=,qr=;
for(int i=;i<=T;i++)h[i]=;
h[S]=;
q[qr++]=S;
while(ql!=qr){
int w=q[ql++];
for(int i=e0[w];i;i=enx[i]){
if(!ev[i])continue;
int u=es[i];
if(h[u])continue;
h[u]=h[w]+;
q[qr++]=u;
}
}
return h[T];
}
int dfs(int w,int f){
if(w==T)return f;
int used=,c;
for(int i=e0[w];i;i=enx[i]){
if(!ev[i])continue;
int u=es[i];
if(h[u]!=h[w]+)continue;
c=f-used;
if(c>ev[i])c=ev[i];
c=dfs(u,c);
ev[i]-=c;
ev[i^]+=c;
used+=c;
if(f==used)return f;
}
if(f!=used)h[w]=;
return used;
}
void addedge(int a,int b,int f){
es[ep]=b;enx[ep]=e0[a];ev[ep]=f;e0[a]=ep++;
es[ep]=a;enx[ep]=e0[b];ev[ep]=;e0[b]=ep++;
}
int xs[]={-,,,};
int ys[]={,-,,};
int qx[],qy[],tag[][],len[][],now=;
bool chk(int X){
int pc=;
S=(n+)*m++X*n*m;T=S+;
for(int i=;i<=T;i++)e0[i]=;ep=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(s[i][j]=='.')addedge(S,i*m+j,),pc++;
if(s[i][j]=='D'){
for(int c=;c<=X;c++)addedge(i*m+j+c*n*m,T,);
int ql=,qr=;
qx[]=i;qy[]=j;qr++;
++now;
tag[i][j]=now;
len[i][j]=;
while(ql<qr){
int x=qx[ql],y=qy[ql];ql++;
if(s[x][y]=='.'&&len[x][y]<=X)for(int c=len[x][y];c<=X;c++)addedge(x*m+y,i*m+j+c*n*m,);
if(len[x][y]<=X)
for(int a=;a<;a++){
int x1=x+xs[a],y1=y+ys[a];
if((s[x1][y1]=='.')&&tag[x1][y1]!=now){
tag[x1][y1]=now;
len[x1][y1]=len[x][y]+;
qx[qr]=x1;qy[qr]=y1;qr++;
}
}
}
}
}
}
while(bfs())pc-=dfs(S,inf);
return !pc;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=;i++)for(int j=;j<=;j++)s[i][j]='X';
for(int i=;i<=n;i++){
scanf("%s",s[i]+);
s[i][m+]='X';
}
int L=,R=n*m+,M;
while(L<R){
M=L+R>>;
if(chk(M))R=M;
else L=M+;
}
while(!chk(L)&&L<=n*m)++L;
while(L>&&chk(L-))--L;
if(L<=n*m)printf("%d\n",L);
else puts("impossible");
return ;
}

bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流的更多相关文章

  1. BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )

    我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...

  2. bzoj 1189: [HNOI2007]紧急疏散evacuate 分层图最大流_拆点_二分

    Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...

  3. BZOJ 1189 [HNOI2007]紧急疏散evacuate

    Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一 ...

  4. BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 412[Submi ...

  5. 【BZOJ】1189: [HNOI2007]紧急疏散evacuate(二分+bfs+网络流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1189 表示完全不会QAQ.... 于是膜拜题解orz 二分时间........... 于是转换成判定 ...

  6. 1189: [HNOI2007]紧急疏散evacuate - BZOJ

    Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一 ...

  7. 1189: [HNOI2007]紧急疏散evacuate

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3831  Solved: 1119[Submit][Status][Discuss] Descript ...

  8. BZOJ1189: [HNOI2007]紧急疏散evacuate(二分答案,最大流)

    Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...

  9. bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate

    http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...

随机推荐

  1. Java基础知识:Java实现Map集合二级联动3

    * Returns an image stored in the file at the specified path * @param path String The path to the ima ...

  2. 最全的Markdown语法

    目录 Markdown语法 多级标题 引用与注释 插入代码 行内代码 代码段 图片 超链接 行内超链接 参数式超链接 字体 表格 分割线 多级列表 无序列表 有序列表 多选框 LaTeX公式 行内La ...

  3. java一些面试题

    java虚拟机 什么时候会触发full gc System.gc()方法的调用 老年代空间不足 永生区空间不足(JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生 ...

  4. css3美化radio样式

    .magic-radio{ position: absolute; display: none; } .magic-radio + label { position: relative; displa ...

  5. matlab 直方图均衡化(含rgb)

    步骤: 统计原图像素每个像素的个数 统计原图像<每个灰度级的像素的累积个数 家里灰度级得映射规则 将原图每个像素点的灰度映射到新图 代码: clear all I=imread('1.jpg') ...

  6. 重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  7. PHP 将一个字符串部分字符用$re替代隐藏

    <?php/** * 将一个字符串部分字符用$re替代隐藏 * @param string $string 待处理的字符串 * @param int $start 规定在字符串的何处开始, * ...

  8. P4语法(1)基础数据类型和Header

    文章学习自:P4语言编程详解 由于原文有一点的年份,所以也继续阅读了相关的最新规范. P4语言规范 基础数据类型 布尔型(bool) 运算符 描述 and 双目运算符,结果为布尔型 or 双目运算符, ...

  9. Beta完结--感想及吐槽

    Beta冲刺结束啦!!! Beta冲刺结束啦!!! Beta冲刺结束啦!!! 这时候每个人的心情肯定都是非常激动的.随着Beta冲刺的结束,折磨了我们一整个学期的软工实践也差不多结束了.(实在是太不容 ...

  10. sublime text 输入法不跟随光标

    1.引子 sublime text 有个BUG,那就是不支持中文的鼠标跟随(和PS类似输入的光标和文字候选框不在一起).如下图: 2.插件 安装IMESupport插件即可插件,这款插件是日本人写的. ...