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. VS code deploy同步服务器代码

    首先在安装“deploy”插件 然后打开settings.json文件加上 { "deploy": { "packages": [ { "name&q ...

  2. luogu4168蒲公英(区间众数)

    luogu4168蒲公英(区间众数) 给定n个数,m个区间询问,问每个询问中的众数是什么. 题面很漂亮,大家可以去看一下. 对于区间众数,由于区间的答案不能由子区间简单的找出来,所以似乎不能用树形结构 ...

  3. 2017-10-7 清北刷题冲刺班p.m

    测试 A 同花顺 文件名 输入文件 输出文件 时间限制 空间限制card.cpp/c/pas card.in card.out 1s 512MB题目描述所谓同花顺,就是指一些扑克牌,它们花色相同,并且 ...

  4. SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式

    一.定时任务 1.基本概念 按照指定时间执行的程序. 2.使用场景 数据分析 数据清理 系统服务监控 二.同步和异步 1.基本概念 同步调用 程序按照代码顺序依次执行,每一行程序都必须等待上一行程序执 ...

  5. git分支主干

    ~/Desktop/work/movies/movie(apps) $ git status  //先查看是否有需要提交的东西# On branch appsnothing to commit (wo ...

  6. [USACO14MAR]破坏Sabotage 二分答案

    题目描述 Farmer John's arch-nemesis, Farmer Paul, has decided to sabotage Farmer John's milking equipmen ...

  7. MarkDown折叠语法

    1.语法代码 程序员的本质 程序的进阶和优化 1.简化人的操作,更少的代码做更多的事情 2.节省时间效率,在更短的时间内做更多的事情 3.占用内存,占更少的内存做更多的事情 <details&g ...

  8. input[checkbox],input[radiobox]的一些问题

    复选框和文字对不齐:checkbox复选框的一些深入研究与理解: 解决方案:复选框或单选框与文字对齐的问题的深入研究与一 实例:实例.

  9. 关于VS2017提示I/O文件操作函数需要加上_s的解决办法

    最近不论是在写网络编程还是在写小项目时候,都会提示让我用加个_s的函数........ 其实加上_s这个函数是为了确保函数的安全性,确保不会有内存不够或者溢出的情况.但是每次都需要重新看一下_s函数的 ...

  10. DB restore point and datagurad

    ######## 12.5.1 Flashing Back a Physical Standby Database to a Specific Point-in-Time The following ...