bzoj1189 [HNOI2007]紧急疏散
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
XXXXX
X...D
XX.XX
X..XX
XXDXX
Sample Output
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]紧急疏散的更多相关文章
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1132 Solved: 412[Submi ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- BZOJ1189 [HNOI2007]紧急疏散evacuate 【二分 + 网络流】
题目 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以从 ...
- BZOJ1189: [HNOI2007]紧急疏散evacuate(二分答案,最大流)
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
[法一]枚举Time(0~N*M): S->'.'(1); 'D'->T(Time); '.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意di ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
- BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )
我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...
随机推荐
- 目标检测的图像特征提取之_LBP特征
LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子:它具有旋转不变性和灰度不变性等显著的优点.它是首先由T. Ojala, M.Pietikäinen ...
- 如何将拷贝过来的数据 *.ibd 文件生效
1.将拷贝的数据文件 "qqq.idb"放在自己的数据库中. 一般存放在 mysql/ data/ databasename 下 2. "qqq.idb" ...
- web.xml中监听器如何顺序加载
最近用到在Tomcat服务器启动时自动加载数据到缓存,这就需要创建一个自定义的缓存监听器并实现ServletContextListener接口, 并且在此自定义监听器中需要用到Spring的依赖注入功 ...
- LeetCode 179 Largest Number 把数组排成最大的数
Given a list of non negative integers, arrange them such that they form the largest number.For examp ...
- D. Time to Raid Cowavans 分块暴力,感觉关键在dp
http://codeforces.com/contest/103/problem/D 对于b大于 sqrt(n)的,暴力处理的话,那么算出每个的复杂度是sqrt(n),就是把n分成了sqrt(n)段 ...
- Unity (反向动力学)IK动画
- 有限状态机在单片机和 Arduino 编程中的应用
有限状态机在单片机和 Arduino 编程中的应用,个人认为在实际中这是一种思想,意味着解决一类问题. 本帖最后由 张飞 于 2015-3-4 20:18 编辑 在单片机编程中,如果在不使用操作系统的 ...
- 关于PCA降维中遇到的python问题小结
由于论文需要,开始逐渐的学习CNN关于文本抽取的问题,由于语言功底不好,所以在学习中难免会有很多函数不会用的情况..... ̄へ ̄ 主要是我自己的原因,但是我更多的把语言当成是一个工具,需要的时候查找就 ...
- Centos 6.5 添加PHP5.6-7.1的源
centOS6.5 安装后 自带的源中php是5.3版本的,对与php一些常用的框架而言 ,已经不能满足需求了: 使用下面的源 就可以更新到php7.1版本了. # rpm -Uvh http://r ...
- Vue2.0搭建脚手架(vue-cli)
一.安装node.js 进入官网下载node.js 二.安装 cnpm 1.说明:npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装.卸载.管理 ...