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. 分享4个未注册*sdn域名

    众所周知msdn和csdn在IT界享有盛誉. Microsoft Developer Network-MSDN Chinese software develop net-CSDN 分享以下4个未注册域 ...

  2. Sqlserver中关于锁

    大多数数据库需要同时处理多个查询,这些查询并不会像车等待红绿灯排队等待,而是会寻找最短的路径执行,因此需要一个红绿灯进行约束,这个红绿灯就是锁 理论上所有的事务之间应该是完全隔离的,但是事实上隔离的成 ...

  3. CI 更新字段

    function update_click_num($brand_id) { $this->db->set('click_num', 'click_num+1', FALSE); $thi ...

  4. C# 微信扫码支付API (微信扫码支付模式二)

    一.SDK下载地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1,下载.NET C#版本: 二.微信相关设置:(微信扫码 ...

  5. The influence of informal governance mechanisms on knowledge integration

    Title:The influence of informal governance mechanisms on knowledge integration within cross-function ...

  6. 为什么要使用jQuery?

    首先必须得了解为什么要学习JQuery,JQuery有哪些优点,当然是相对于传统的Javascript和DOM来说了,现在将JQuery的优势总结如下: 1,轻量级. JQuery非常小,压缩包只有1 ...

  7. Android知识思维导图

    注:图片来源于网络,谢谢分享. 一.  项目目录结构: 布局控件 ListVIew控件 Widget:(窗口小部件) Activity Manager 二.  应用程序的5个模块构成: Activit ...

  8. 关于IE8以上 不引人css 症状

    不知道各位有没有体验过 这样的状况  在同一个文件夹中 <!DOCTYPE html> <html> <head> <meta charset="u ...

  9. Apache 编译安装

    # wget http://www.apache.org/dist/httpd/httpd-2.2.9.tar.gz  (此处我是直接用的下载好的包) # tar -zxvf httpd-2.2.9. ...

  10. 看了些关于rem的知识点,在这做个自我总结归纳

    我们最常用的字体单位是PX和EM. 首先px: px像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的.(引自CSS2.0手册) px会随着屏幕分辨率的改变而改变,但是浏览器对页 ...