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

先bfs出最短路,再枚举时间t,用网络流来判断是否可以安全撤离(至于怎么证明它的正确性,我不知道,网上到处都是这样写的)

本来一直纠结在dis这个距离标号,我想继续利用上次的标号,后来发现不行因为断层以后,有的点距离标号变成最大的,就不能再经过它了,当时调了好久的说

 const
fx:array[..]of longint=(,,-,);
fy:array[..]of longint=(,,,-);
var
map:array[..,..]of char;
node:array[..,..]of longint;
f:array[..,..,..]of longint;
door:array[..,..]of longint;
n,m,menn,doorn,tot:longint; procedure init;
var
i,j:longint;
begin
readln(n,m);
for i:= to n do
begin
for j:= to m do
begin
read(map[i,j]);
if map[i,j]='.' then
begin
inc(menn);
inc(tot);
node[i,j]:=tot;
end;
if map[i,j]='D' then
begin
inc(doorn);
door[doorn,]:=i;
door[doorn,]:=j;
inc(tot);
node[i,j]:=tot;
end;
end;
readln;
end;
end; var
flag,vis:array[..,..]of boolean;
x,y:array[..]of longint; procedure bfs;
var
i,j,head,tail:longint;
begin
fillchar(f,sizeof(f),<<);
fillchar(vis,sizeof(vis),true);
for i:= to doorn do
begin
fillchar(flag,sizeof(flag),true);
f[door[i,],door[i,],i]:=;
head:=;
tail:=;
x[]:=door[i,];
y[]:=door[i,];
flag[x[],y[]]:=false;
while head<=tail do
begin
for j:= to do
if (x[head]+fx[j]>)and(x[head]+fx[j]<=n)and(y[head]+fy[j]>)and(y[head]+fy[j]<=m) then
if map[x[head]+fx[j],y[head]+fy[j]]='.' then
if flag[x[head]+fx[j],y[head]+fy[j]] then
begin
inc(tail);
x[tail]:=x[head]+fx[j];
y[tail]:=y[head]+fy[j];
vis[x[tail],y[tail]]:=false;
f[x[tail],y[tail],i]:=f[x[head],y[head],i]+;
flag[x[tail],y[tail]]:=false;
end;
inc(head);
end;
end;
for i:= to n do
for j:= to m do
if (map[i,j]='.')and(vis[i,j]) then
begin
write('impossible');
halt;
end;
end; var
a:array[..,..]of longint;
dis,vh,pre,his:array[..]of longint;
flow,time,aug,num,min,hui:longint;
find:boolean; procedure sap;
var
i,j,k:longint;
begin
aug:=maxlongint;
fillchar(vh,sizeof(vh),);
vh[]:=num+;
fillchar(dis,sizeof(dis),);
i:=;
while dis[]<=num do
begin
his[i]:=aug;
find:=false;
for j:= to num+ do
if (a[i,j]>)and(dis[i]=dis[j]+) then
begin
find:=true;
if aug>a[i,j] then aug:=a[i,j];
pre[j]:=i;
i:=j;
if i=hui then
begin
inc(flow,aug);
while i<> do
begin
k:=pre[i];
inc(a[i,k]);
dec(a[k,i]);
i:=k;
end;
aug:=maxlongint;
end;
break;
end;
if find then continue;
min:=num;
for j:= to num+ do
if (a[i,j]>)and(min>dis[j]) then min:=dis[j];
dec(vh[dis[i]]);
inc(vh[min+]);
if vh[dis[i]]= then break;
dis[i]:=min+;
if i<> then
begin
i:=pre[i];
aug:=his[i];
end;
end;
end; procedure work;
var
i,j,k:longint;
begin
num:=menn+doorn+;
hui:=num+;
for i:= to n do
for j:= to m do
if map[i,j]='.' then inc(a[,node[i,j]]);
while flow<menn do
begin
inc(time);
for i:= to n do
for j:= to m do
if map[i,j]='.' then
for k:= to doorn do
if f[i,j,k]=time then inc(a[node[i,j],node[door[k,],door[k,]]]);
for i:= to doorn do
inc(a[node[door[i,],door[i,]],hui]);
sap;
end;
write(time);
end; begin
init;
bfs;
work;
end.

1189: [HNOI2007]紧急疏散evacuate - BZOJ的更多相关文章

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

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

  2. bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流

    [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3626  Solved: 1059[Submit][St ...

  3. AC日记——[HNOI2007]紧急疏散evacuate bzoj 1189

    [HNOI2007]紧急疏散evacuate 思路: 处理每个人到门的最短路: 然后二分答案: s向人连边流量1: 人向门拆分后的点连边流量1(拆成400,前一个点连当前点流量INF): 然后门向t连 ...

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

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

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

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

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

    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. bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate

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

  9. Bzoj1189 [HNOI2007]紧急疏散evacuate

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2293  Solved: 715 Descr ...

随机推荐

  1. 详解Win2003 IIS6.0 301重定向带参数的问题(转摘)

      网站更换域名,把旧域名用301指到新域名来. 从iis中设置url永久转向就可以,看上去很容易,用了一会儿才发现,参数都没有带上. 从微软网站上找到如下说明,果然好使: 重定向参考 (IIS 6. ...

  2. HDOJ2024C语言合法标识符

    C语言合法标识符 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. android——获取ImageView上面显示的图片bitmap对象

    获取的函数方法为:Bitmap bitmap=imageView.getDrawingCache(); 但是如果只是这样写我们得到的bitmap对象可能为null值,正确的方式为: imageView ...

  4. JQuery中操作表单和表格

    一:表单应用 1.HTML中的表单大致由三部分组成 (1).表单便签:包含处理表单数据所用的服务端程序URL,以及数据提交到服务器的方法. (2).表单域:包含文本框.密码框.隐藏域.多行文本框.复选 ...

  5. iOS动画——弹窗动画(pop动画)

    用pop动画简单实现弹窗的缩放和渐变,感觉这个动画常用,就写一下博客 pop动画是Facebook推出的动画引擎,请自行到GitHub上搜索下载拖拽导入xcode项目中. 更多pop动画使用和原理可网 ...

  6. NSUserDefaults存储自定义对象

    场景是这样的: 现在有一个数组如下,数组中存放着自定义的对象GoodscCategory <__NSArrayM 0x7ffb9c2032b0>( <GoodscCategory: ...

  7. Word 2003 出现 向程序发送命令时出现问题 的 解决方案

    这种原因出现的问题是word的模板出现问题. 解决方案是重新让word生成Norma.dot文档. 步骤: 1,按住视窗键+R或者开始菜单搜索文件和程序,粘贴 %appdata%\microsoft\ ...

  8. 打包并发布自己的Android应用(eclipse)

    第一步,在Eclipse中选择需要打包的项目,然后右键--选择Export,会弹出一个打包的提示框,如下图所示. 按Next之后,会继续出现一个提示框,这里你可以选择自己需要打包的项目(默认是刚才选中 ...

  9. @Autowired与@Resource用法

    官方文档中有这样一段话. If you intend to express annotation-driven injection by name, do not primarily use @Aut ...

  10. C++记录2

    1, 求成员变量的偏移: 2, const实现机制:在编译期间完成,对于内置类型,如int, 编译器可能使用常数直接替换掉对此变量的引用.而对于结构体不一定. 编译器在优化代码时把j直接优化成64h了 ...