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. C博客作业--指针

    一.PTA实验作业 题目1:输出月份英文名 1. 本题PTA提交列表 2. 设计思路 3.代码截图 4.本题调试过程碰到问题及PTA提交列表情况说明. 选择这一题是因为这道题的通过率较低.为什么会这样 ...

  2. 20162330 第十二周 蓝墨云班课 hash

    题目要求 利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75) 关键字集合:85,75,57,60,65,(你的8位学号 ...

  3. verilog学习笔记(0)

    assign赋值语句根本不允许出现在always语句块中 位于begin/end块内的多条阻塞赋值语句是串行执行的; 但是多条非阻塞赋值语句却是并行执行的,这些非阻塞赋值语句都会在其中任何一条语句执行 ...

  4. JAVA接口基础知识总结

    1:是用关键字interface定义的. 2:接口中包含的成员,最常见的有全局常量.抽象方法. 注意:接口中的成员都有固定的修饰符. 成员变量:public static final     成员方法 ...

  5. 使用XIB实现嵌套自定义视图

    在进行iOS开发的过程中,对于一些复杂的界面,我们可以通过Interface Builder这个Xcode集成的可视化界面编辑工具在完成,这回节省大部分时间以及代码量.它的使用方法这里不做介绍了,这次 ...

  6. Flask 学习 八 用户角色

    角色在数据库中表示 app/models.py class Role(db.Model): __tablename__='roles' id = db.Column(db.Integer,primar ...

  7. Hibernate之Hibernate的下载与安装

    Hibernate用法十分简单,当我们在Java项目中引入Hibernate框架之后,就能以面向对象的方式来操作关系数据库了. 下载: 登陆Hibernate官网,下载Hibernate压缩包,win ...

  8. New UWP Community Toolkit - AdaptiveGridView

    概述 UWP Community Toolkit  中有一个自适应的 GridView 控件 - AdaptiveGridView,本篇我们结合代码详细讲解  AdaptiveGridView 的实现 ...

  9. 【转】Python处理wave文件

    #本文PDF版下载 Python解析Wav文件并绘制波形的方法 #本文代码下载 Wav波形绘图代码 #本文实例音频文件night.wav下载 音频文件下载 (石进-夜的钢琴曲) 前言 在现在繁忙的生活 ...

  10. 【learning】多项式相关(求逆、开根、除法、取模)

    (首先要%miskcoo,这位dalao写的博客(这里)实在是太强啦qwq大部分多项式相关的知识都是从这位dalao博客里面学的,下面这篇东西是自己对其博客学习后的一些总结和想法,大部分是按照其博客里 ...