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

C++语言请用scanf("%s",s)读入!

正解:最大流。

比较经典的按时间拆点的最大流套路。首先预处理出每个空地到每个门需要的距离,然后把所有门按照时间拆点。如果空地到这个点的时刻为$t$,那么则把空点向这个点时刻$t$对应的点连边,同时每个门的前一时间向后一时间连流量为$inf$的边,使得空地也可以使用后面的时间对应的点,其他流量都为$1$。我们可以从小到大枚举时间,然后把当前时间的点和边加入图中,跑残量网络就行了,当满流时就输出当前时间。无解情况很好判断,只要一个空地不能到达所有的门,那么就无解了。

 //It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1061109567)
#define N (3000010)
#define il inline
#define RG register
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; struct edge{ int nt,to,flow,cap; }g[N]; int qx[],qy[],dep[],a[][],b[][],vis[][],dis[][];
int head[N],cur[N],d[N],q[N],S,T,n,m,num,cnt,cnt1,cnt2,flow;
char s[][]; const int d1[]={,,-,};
const int d2[]={,,,-}; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG int from,RG int to,RG int cap){
g[++num]=(edge){head[from],to,,cap},head[from]=num; return;
} il int bfs(RG int S,RG int T){
memset(d,,sizeof(d)),d[S]=;
RG int h=,t=; q[t]=S;
while (h<t){
RG int x=q[++h],v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to;
if (!d[v] && g[i].cap>g[i].flow){
d[v]=d[x]+,q[++t]=v;
if (v==T) return ;
}
}
}
return ;
} il int dfs(RG int x,RG int T,RG int a){
if (!a || x==T) return a; RG int flow=,f,v;
for (RG int &i=cur[x];i;i=g[i].nt){
v=g[i].to;
if (d[v]==d[x]+ && g[i].cap>g[i].flow){
f=dfs(v,T,min(a,g[i].cap-g[i].flow));
if (!f){ d[v]=; continue; }
g[i].flow+=f,g[i^].flow-=f;
flow+=f,a-=f; if (!a) return flow;
}
}
return flow;
} il int maxflow(RG int S,RG int T){
RG int flow=;
while (bfs(S,T)){
memcpy(cur,head,sizeof(head));
flow+=dfs(S,T,inf);
}
return flow;
} il void spfa(RG int id,RG int x,RG int y){
memset(vis,,sizeof(vis)),vis[x][y]=;
RG int h=,t=; qx[t]=x,qy[t]=y,dep[t]=;
while (h<t){
x=qx[++h],y=qy[h]; RG int X,Y;
for (RG int i=;i<;++i){
X=x+d1[i],Y=y+d2[i];
if (X<= || X>n || Y<= || Y>m) continue;
if (vis[X][Y] || s[X][Y]=='X') continue;
if (b[X][Y]) dis[id][b[X][Y]]=dep[h]+;
else vis[X][Y]=,qx[++t]=X,qy[t]=Y,dep[t]=dep[h]+;
}
}
return;
} il void work(){
n=gi(),m=gi(),num=,memset(dis,0x3f3f3f,sizeof(dis));
for (RG int i=;i<=n;++i){
scanf("%s",s[i]+);
for (RG int j=;j<=m;++j){
if (s[i][j]=='.') a[i][j]=++cnt1;
if (s[i][j]=='D') b[i][j]=++cnt2;
}
}
for (RG int i=;i<=n;++i)
for (RG int j=;j<=m;++j) if (a[i][j]) spfa(a[i][j],i,j);
for (RG int i=,fg;i<=cnt1;++i){
fg=;
for (RG int j=;j<=cnt2;++j)
if (dis[i][j]<inf){ fg=; break; }
if (!fg){ puts("impossible"); return; }
}
cnt=cnt1,S=++cnt,T=++cnt;
for (RG int i=;i<=cnt1;++i) insert(S,i,),insert(i,S,);
for (RG int i=;i<=cnt2;++i) insert(++cnt,T,),insert(T,cnt,);
for (RG int i=;i<=cnt1;++i)
for (RG int j=;j<=cnt2;++j)
if (dis[i][j]==) insert(i,cnt-cnt2+j,),insert(cnt-cnt2+j,i,);
if ((flow=maxflow(S,T))==cnt1){ puts(""); return; }
for (RG int ans=;;++ans){
for (RG int i=;i<=cnt2;++i){
insert(++cnt,T,),insert(T,cnt,);
insert(cnt-cnt2,cnt,inf),insert(cnt,cnt-cnt2,);
}
for (RG int i=;i<=cnt1;++i)
for (RG int j=;j<=cnt2;++j)
if (dis[i][j]==ans) insert(i,cnt-cnt2+j,),insert(cnt-cnt2+j,i,);
if ((flow+=maxflow(S,T))==cnt1){ printf("%d\n",ans); return; }
}
return;
} int main(){
File("evacuate");
work();
return ;
}

bzoj1189 [HNOI2007]紧急疏散的更多相关文章

  1. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

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

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

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

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

  4. BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)

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

  5. BZOJ1189 [HNOI2007]紧急疏散evacuate 【二分 + 网络流】

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

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

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

  7. 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate

    [法一]枚举Time(0~N*M): S->'.'(1); 'D'->T(Time); '.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意di ...

  8. 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流

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

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

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

随机推荐

  1. 洛谷P2607 [ZJOI2008]骑士

    P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...

  2. IOS Swift UITableViewcontroller实现点击空白处隐藏键盘

    在ios开发中,为了方便,我们经常使用UITableViewcontroller,比如搜索界面为了方便可能更多的使用UITableViewcontroller,那么问题就来了,当我点击搜索框的时候会弹 ...

  3. 我的省选 Day -14

    Day -14 07:43:27 到机房了,不知道早上要做什么题,要不去选一题NOI原题来试试水好了 (因为NOI的原题质量比较有保证吧..) 09:11:22 正在做NOI2016的网格 开始写自己 ...

  4. css3旋转立方体-_-

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. php微信公众号开发简单记录

    开发前准备:1.服务器 2.微信公众号测试号(有真实的账号更好) 测试号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/lo ...

  6. ERROR: Unable to globalize '/usr/local/NONE/etc/php-fpm.d/*.conf' (ret = 2) from /usr/local/etc/php-fpm.conf at line WARNING: Nothing matches the include pattern '/usr/local/php7/etc/php-fpm.d/*.conf'

    Building from source is not easy if something is a bit different, and I had a hard time with some di ...

  7. 15-----float(浮动)

    浮动 浮动是css里面布局最多的一个属性,也是很重要的一个属性. float:表示浮动的意思.它有四个值. none: 表示不浮动,默认 left: 表示左浮动 right:表示右浮动 看一个例子: ...

  8. ubuntu搭建mediawiki

    1.搭建lamp环境,lamp指的是: Linux+Apache+Mysql/MariaDB+Perl/PHP/Python (我们安装的是Linux+apache2+postgresql+php) ...

  9. ArrayList相关方法介绍及源码分析

    目录 ArrayList简介: ArrayList 相关方法介绍 代码表示 相关方法源码分析 ArrayList简介: java.util.ArrayList 是我们最常用的一个类,ArrayList ...

  10. android 开发-(Contextual Menu)上下文菜单的实现

    在android3.0以后,安卓设备不在提供物理的菜单按键,同时,android应用提供了另外的菜单实现机制,来替代之前的菜单创建方式.安卓设备中,平常可以使用长按住某个内容弹出菜单选项.这就是我们需 ...