1689: [HNOI2007]紧急疏散evacuate

时间限制: 1 Sec  内存限制: 128 MB

题目描述

发生了火警,所有人员需要紧急疏散!假设每个房间是一个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
   因为每一秒门只能出一个人,所以人可能堵住。因此要把门按时间拆点,
   而答案为二分时间,只要求出空地到每扇门的最短路(最短时间),然后把此空地与门连接(时间为最短路径到二分的时间),边权为一。
    注意拆出的新点标号别重复。。身败名裂。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
#define inf 100000000
using namespace std;
int n,m,a[404][404],cnt=0,door[404],peo[404];
int tim[404][704],adj[5000000],s=0,dep[5000000],e;
int S=0,T;
char tu[25][25];
struct node
{int v,l,next;
} lu[5000100];
void add(int u,int v,int l)
{lu[++e].v=v;lu[e].next=adj[u];adj[u]=e;lu[e].l=l;}
int bfs()
{memset(dep,0,sizeof(dep));queue<int> q;dep[S]=1;q.push(S);while(!q.empty()){int x=q.front();q.pop();for(int i=adj[x];i!=-1;i=lu[i].next){int to=lu[i].v;if(!dep[to]&&lu[i].l){dep[to]=dep[x]+1;if(to==T)return 1;q.push(to);}}}return 0;
}
int dfs(int x,int fw){if(x==T) return fw;int tmp=fw,k;for(int i=adj[x];i!=-1;i=lu[i].next){int v=lu[i].v;if(lu[i].l && tmp && dep[v]==dep[x]+1){k=dfs(v,min(tmp,lu[i].l));if(!k){dep[v]=0;continue;}lu[i].l-=k; lu[i^1].l+=k; tmp-=k;}}return fw-tmp;
}
int check(int len)
{memset(adj,-1,sizeof(adj));e=0;int sum=cnt;for(int i=1;i<=cnt;i++)if(door[i])for(int j=1;j<=len;j++)tim[i][j]=(i-1)*len+cnt;T=300000;for(int i=1;i<=cnt;i++)if(peo[i]){add(S,i,1),add(i,S,0);for(int j=1;j<=cnt;j++)if(door[j]){int k=a[i][j];for(k=a[i][j];k<=len;k++)add(i,tim[j][k],1),add(tim[j][k],i,0);}}for(int i=1;i<=cnt;i++)if(door[i]){for(int j=1;j<=len;j++)add(tim[i][j],T,1),add(T,tim[i][j],0);}int ans=0,tt;while(bfs())ans+=dfs(S,inf);if(ans>=s)return 1;return 0;
}
int main()
{
//  freopen("data.in","r",stdin);
//  freopen("data.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%s",tu[i]+1);memset(a,30,sizeof(a));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cnt++;if(tu[i][j]=='.'){s++;peo[cnt]=1;if(i!=1&&(tu[i-1][j]=='.'||tu[i-1][j]=='D'))a[cnt][cnt-m]=1,a[cnt-m][cnt]=1;if(i!=n&&(tu[i+1][j]=='.'||tu[i+1][j]=='D'))a[cnt][cnt+m]=1,a[cnt+m][cnt]=1;if(j!=1&&(tu[i][j-1]=='.'||tu[i][j-1]=='D'))a[cnt][cnt-1]=1,a[cnt-1][cnt]=1;if(j!=m&&(tu[i][j+1]=='.'||tu[i][j+1]=='D'))a[cnt][cnt+1]=1,a[cnt+1][cnt]=1;}if(tu[i][j]=='D'){door[cnt]=1;}}for(int k=1;k<=cnt;k++)for(int i=1;i<=cnt;i++)for(int j=1;j<=cnt;j++) if(a[i][j]>a[i][k]+a[k][j])a[i][j]=a[i][k]+a[k][j];for(int i=1;i<=cnt;i++)if(peo[i]){int p=1;for(int j=1;j<=cnt;j++)if(door[j]&&a[i][j]<1000){p=0;break;}if(p==1){printf("impossible");exit(0);}       }int l=0,r=600,mid,ans=600;while(l<=r){mid=(l+r)/2;if(check(mid))r=mid-1,ans=mid;elsel=mid+1;}printf("%d",ans);
}

转载于:https://www.cnblogs.com/QTY2001/p/7632766.html

最大流 紧急疏散evacuate相关推荐

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

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

  2. bzoj1189 [HNOI2007]紧急疏散evacuate(二分答案+bfs+最大流判是否满流)

    首先bfs处理出每个人到每个门所需的时间.然后二分答案,对于所有人能到的所有门,建边,边权为1,从源点向所有人建边,边权为1,从所有门向汇点建边,边权为mid(最多出去mid个人),dinic跑最大流 ...

  3. bzoj1189 [HNOI2007]紧急疏散EVACUATE spfa+网络流+二分

    这个题是非常暴力的匹配问题. 首先最好想的思路是给每个人分门的决策, 每个人到每个门的距离直接暴力最短路即可 但不能算出一个门被多个人经过的情况 所以就有了暴力的想法,再给每个人.对每一个门分配一个时 ...

  4. 有趣题目和认知合集(持续更新)

    写写对一些算法的理解,挂几个有意思的题,可能也会挂几个板子题 算法理解偏向于能懂即可,没有严格的证明 快乐几何 [1.2]Volatile Kite 点到直线 快乐搜与暴力 [2.4]Short Co ...

  5. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  6. 2019.4.summary

    2019.4.1 BZOJ1061: [Noi2008]志愿者招募 真心有点难QAQ https://www.byvoid.com/zhs/blog/noi-2008-employee 看void爷的 ...

  7. [线性规划与网络流24题] 网络流常见模型

    最近两个月在做<线性规划与网络流24题>这套题,加深了对网络流的理解. 涵盖到的模型有:二分图匹配.二分图的最大独立集.最大权闭合图.有向无环图的最小路径覆盖.最多不相交路径.最大权不相交 ...

  8. 限流式保护器在建筑地下车库防火中的应用与研究

    前言  当前地下车库成为缓解停车难的主要手段,但随着地下车库数量的增加,对地下车库设计标准也提出了更高的要求.在地下车库防火设计过程中,影响其设计的因素较多,因此要基于实际情况入手,针对各项设计指标进 ...

  9. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  10. 如何判断飞机的年限_技术流带你鉴定前风挡玻璃更换,不再使用日期判断!

    ​ 这又是一篇关于前风挡玻璃鉴定的文章,我记得在二手车鉴定微信公众号里面已经发布好几篇这样的文章了,当然每篇文章的住重点不同,今天这一篇应该是完结篇,它们在一起能组成一套玻璃更换系列专题课程: 我们回 ...

最新文章

  1. 安防行业标准规范大全
  2. 操作系统都是用c语言写的吗,用C语言写关于操作系统的一个问题。
  3. 【linux】Linux查看服务器登陆用户信息命令(w、last、who)详解
  4. Swift基础语法: 30 - Swift的基类, 子类, 重写, 重写方法, 重写属性, 防止重写
  5. 关于服务器虚化的优势,vmware虚化优势.docx
  6. IIS部署VUE刷新404问题如何解决?
  7. Android Java调用ffmpeg命令
  8. 深度神经网络 分布式训练 动手学深度学习v2
  9. 测试5g网速的软件排行榜,2021网络测速app排行榜-手机网速测试软件推荐
  10. 用Multisim13.0进行混频器的仿真
  11. Math.abs()方法
  12. 3D游戏里的男女性角色模型是这样建模出来的
  13. 跨境知道快讯:亚马逊推出“Buy with Prime”服务
  14. JavaCV人脸识别三部曲之三:识别和预览
  15. qt show widget_Qt Widget不显示
  16. win10系统卷影复制服务器,卷影复制Windows 10与全能备份软件
  17. 方舟上的李德磊--记方舟科技董事长兼总裁李德磊校友
  18. VS2010 学习C++动态链接库的创建与使用(带实例代码)
  19. Ubuntu 18.04(16.04)搭建tftp服务器
  20. 如何做兼职?怎么找正规的网络兼职平台(十大正规兼职平台)

热门文章

  1. 程序员搞什么副业好?
  2. Backend For Frontend 实践心得
  3. 中继器 网桥 路由器 网关
  4. 常见的笔记本电池使用技巧
  5. js改变html font size,JavaScript fontsize方法入门实例(按照指定的尺寸来显示字符串)...
  6. 用计算机数字技术制作的电影是,计算机数字技术为电影带来的空前发展.doc
  7. 2021年安全生产模拟考试(全国特种作业操作证高处作业-高处安装维护拆除模拟考试题库二)安考星
  8. Flutter系列之设置Dialog的宽度
  9. 微型计算机的主机通常指什么,微型机主机是指什么
  10. vue在移动端实现禁用物理返回键