1689: [HNOI2007]紧急疏散evacuate

题目描述

发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是".",那么表示这是一块空地;如果是"X",那么表示这是一面墙,如果是"D",那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。

输入

输入文件第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,以下N行M列描述一个N M的矩阵。其中的元素可为字符"."、"X"和"D",且字符间无空格。

输出

只有一个整数K,表示让所有人安全撤离的最短时间,如果不可能撤离,那么输出"impossible"(不包括引号)。

样例输入

5 5
XXXXX
X...D
XX.XX
X..XX
XXDXX

样例输出

3

  一道网络流的题:我们发现时间是满足单调性的,所以可以二分时间logn的复杂度,在当前时间限制下,将原点与每个人相连,每个人于能到达的不同时刻的每个门相连,意思是要将每个门拆点,拆成在不同时刻的门。所以要预处理出每个人到每个门的最短距离,跑一边dfs,再由这些门与汇点相连,这些边的容量为一;在这道题上炮最大流就行了,当且仅当最大流的数值等于总人数是,此时间点是可行的。
  如果最终结果为你二分的上界的话:意思是没有这种情况,cout<<impossible;所以上界要定的稍大一些; 附代码:
  
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define inf 5000000
map<pair<int,int>,int>ma;
int n,m,num,cnt,shu;
int pos[][],id[][],dis[][];
char s[][];int adj[];
struct flow{
int s,t,w,next;
}k[];
int read(){
int sum=;char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<=''){sum=sum*+ch-'';ch=getchar();}
return sum;
}
void dfs(int fa,int cnt,int x,int y){
if(pos[x-][y]==){
if(dis[fa][id[x-][y]]>dis[fa][cnt]+){
dis[fa][id[x-][y]]=dis[fa][cnt]+;
dfs(fa,id[x-][y],x-,y);
}
}
if(pos[x+][y]==){
if(dis[fa][id[x+][y]]>dis[fa][cnt]+){
dis[fa][id[x+][y]]=dis[fa][cnt]+;
dfs(fa,id[x+][y],x+,y);
}
}
if(pos[x][y-]==){
if(dis[fa][id[x][y-]]>dis[fa][cnt]+){
dis[fa][id[x][y-]]=dis[fa][cnt]+;
dfs(fa,id[x][y-],x,y-);
}
}
if(pos[x][y+]==){
if(dis[fa][id[x][y+]]>dis[fa][cnt]+){
dis[fa][id[x][y+]]=dis[fa][cnt]+;
dfs(fa,id[x][y+],x,y+);
}
}
}
void search(int x,int y){
dis[id[x][y]][id[x][y]]=;
dfs(id[x][y],id[x][y],x,y);
}
void init(int s,int t,int w){
k[num].s=s;k[num].t=t;k[num].w=w;
k[num].next=adj[s];adj[s]=num++;
}
void build(int lim){
num=;memset(adj,-,sizeof(adj));
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
if(pos[i][j]==)
init(,id[i][j],),init(id[i][j],,);
if(pos[i][j]==){
for(int u=;u<=lim;++u)
init(ma[make_pair(id[i][j],u)],,),init(,ma[make_pair(id[i][j],u)],);
for(int u=;u<=n;++u)
for(int p=;p<=m;++p)
if(pos[u][p]==)
for(int b=dis[id[i][j]][id[u][p]];b<=lim;++b)
init(id[u][p],ma[make_pair(id[i][j],b)],),init(ma[make_pair(id[i][j],b)],id[u][p],); }
}
}
int dp[];
bool bfs(){
memset(dp,,sizeof(dp));
queue<int>q;
q.push();dp[]=;
while(!q.empty()){
int o=q.front();q.pop();
for(int i=adj[o];i!=-;i=k[i].next){
if(!k[i].w||dp[k[i].t]) continue;
dp[k[i].t]=dp[o]+;
if(k[i].t==) return true;
q.push(k[i].t);
}
}
return false;
}
int Dfs(int o,int fw){
if(o==) return fw;
int tmp=fw,u;
for(int i=adj[o];i!=-;i=k[i].next){
if(!k[i].w||!tmp||dp[k[i].t]!=dp[o]+) continue;
u=Dfs(k[i].t,min(k[i].w,tmp));
if(!u){
dp[k[i].t]=;continue;
}
k[i].w-=u;k[i^].w+=u;tmp-=u;
}
return fw-tmp;
}
bool judge(int ti){
build(ti);
int ans=;
while(bfs())
ans+=Dfs(,inf);
if(ans==shu) return true;
else return false;
}
int erfen(int l,int r){
if(l==r) return l;
int mid=(l+r)>>;
if(judge(mid))
return erfen(l,mid);
else
return erfen(mid+,r);
}
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
n=read();m=read();
memset(adj,-,sizeof(adj));
memset(pos,0x3f,sizeof(pos));
memset(dis,0x3f,sizeof(dis));
for(int i=;i<=n;++i)
scanf("%s",s[i]);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(s[i][j-]=='D')
pos[i][j]=,id[i][j]=++cnt;
else if(s[i][j-]=='.')
pos[i][j]=,id[i][j]=++cnt,shu++;
cnt=n*m;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(pos[i][j]==)
for(int u=;u<=;++u)
ma[make_pair(id[i][j],u)]=++cnt;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(pos[i][j]==)
search(i,j);
int ans=erfen(,);
if(ans==) printf("impossible");
else printf("%d\n",ans);
return ;
}
 

紧急疏散evacuate的更多相关文章

  1. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

  2. BZOJ-1189 紧急疏散evacuate BFS预处理+最大流+二分判定+神建模!!

    绝世污题,垃圾题,浪费我一整天青春! 1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1262 ...

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

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

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

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

  5. [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)

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

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

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

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

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

  8. 【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE

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

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

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

随机推荐

  1. 学号:201621123032 《Java程序设计》第10周学习总结

    1:本周学习总结 1.1.:以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2:书面作业 2.1.:常用异常--结合题集题目7-1回答 2.1.1:自己以前编写的代码中经常出现什么异常.需要捕 ...

  2. webView调用系统地图,电话,和跳转链接的方法

    webView.dataDetectorTypes = UIDataDetectorTypePhoneNumber | UIDataDetectorTypeLink | UIDataDetectorT ...

  3. 201421123042 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  4. Ajax 的onreadystatechange事件注意事项.

    <script type="text/javascript"> function createXHR() { var request = false; try { re ...

  5. MySQL Group Relication 部署环境入门篇

      一:环境介绍   cenos 6.7 版本 数据库的版本5.7.19 二:部署规划单机多实例的部署   端口号 数据目录  group_repplicatoon 通信接口   3307 /data ...

  6. 新概念英语(1-5)Nice to meet you.

    Is Chang-woo Chinese? Blake:Good morning. B:Good morning, Mr Blake. Blake:This is Miss Sophie Dupont ...

  7. C# bootstrap之表格动态绑定值

    这段时间研究了下bootstrap,打算从表格开始学习,实现动态绑定值,在网上找了挺多例子,但是很少有写全的,要不就太复杂,实现效果后总结一下,直接拷贝过去可以用. 第一步:先去官网上下载bootst ...

  8. IPv6原理、应用与实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯微信技术架构部团队 2017年11月26日,中共中央办公厅和国务院办公厅印发了<推荐互联网协议第六版(IPv6)规模部署行动 ...

  9. 19届华为实习生笔试之判断iPv6地址类型

    题二: 答案: #coding=utf-8 import re,sys str = sys.stdin.readline().strip() def regex(str): result = &quo ...

  10. 将Tomcat添加进服务启动

    tomcat有解压版和安装版2种版本,安装版已经做好了将tomcat添加进服务的操作,而解压版需要我们自己来实现,应用场景主要是在服务器端需要在服务器启动时就启动tomcat. 1.首先需要配置好jd ...