[HNOI2007]紧急疏散evacuate

时间限制: 1 Sec  内存限制: 128 MB
提交: 60  解决: 10

题目描述

发生了火警,所有人员需要紧急疏散!假设每个房间是一个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

提示

solution

这道题就是典型的网络流拆点,因为在每一时刻每一个门都能都能出去一个人,假设一个人到一个门的距离为x,那么他可以在x这个时间点以后,从这个门出去,就把门拆成不同的时间点,然后就可以二分总时间,然后把这个人与这个门从x到枚举的时间连一个流量为1的边,把所有的人与所有的门都这么处理,再把每一时刻的门与汇点连一条流量为1的边,在源点与每个人连一条流量为一的边,这样就能保证每个人只出去一次,每一时刻的门只出去一个人,之后在二分判断的时候,若最大流小于总人数返回非,大于等于总人数就返回真;

  在间的时候可以吧不同时刻的门看成一个矩阵,这样既可以根据行列性质直接算出他们的标号,然后根据之前有的标号,同意加上一个值避免重复即可

  1 #include<cmath>
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<iostream>
  7 #include<algorithm>
  8 #define INF 1000000
  9 using namespace std;
 10
 11 int zhao;
 12 int n,m,peo;
 13 int a[30][30];
 14 int dor[30];
 15 int id[30][30];
 16 int dis[410][410];
 17 int mov[6][3];
 18 int jia;
 19 int S,T;
 20
 21 struct node{
 22     int u,v,w,nxt;
 23 }g[5000100];
 24 int adj[5000100],e;
 25 void add(int u,int v,int w){
 26     g[e].v=v; g[e].u=u; g[e].w=w;
 27     g[e].nxt=adj[u]; adj[u]=e++;
 28 }
 29 bool Jud(int x,int y,int i,int pos){
 30     int x1=x+mov[i][0] ,y1=y+mov[i][1];
 31     if(!(x1>=1 && x1<=n && y1>=1 && y1<=m)) return 0;
 32     if(a[x1][y1]==0 || a[x1][y1]==2) return 0;
 33     int pos2=(x+mov[i][0]-1)*m+ ( y+mov[i][1] );
 34     if(dis[pos2][pos]<10000) return 0;
 35     return 1;
 36 }
 37 void find_short(int pos){
 38     queue<int> q;
 39     q.push(pos);
 40     dis[pos][pos]=0;
 41     int k;
 42     int x,y;
 43     while(!q.empty()){
 44         k=q.front(); q.pop();
 45         //cout<<"k== "<<k<<endl;
 46         x=(k-1)/m+1; y=k%m; if(y==0) y=m;
 47         for(int i=1;i<=4;i++){
 48             if(Jud(x,y,i,pos)){
 49                 int pos2=(x+mov[i][0]-1)*m+ ( y+mov[i][1] );
 50                 dis[pos2][pos]=dis[k][pos]+1;
 51                 //cout<<"pos== "<<pos2<<"  "<<pos<<"  "<<dis[pos2][pos]<<endl;
 52                 q.push(pos2);
 53             }
 54         }
 55     }
 56 }
 57 void init(){
 58     scanf("%d%d",&n,&m);
 59     jia=n*n;
 60     char s[30];
 61     for(int i=1;i<=n;i++){
 62         scanf("%s",&s);
 63         for(int j=0;j<m;j++){
 64             if(s[j]=='.')      a[i][j+1]=1,peo++;
 65             else if(s[j]=='X') a[i][j+1]=0;
 66             else if(s[j]=='D') a[i][j+1]=2;
 67         }
 68     }
 69     for(int i=1;i<=n;i++)
 70         for(int j=1;j<=m;j++){
 71             id[i][j]=m*(i-1)+j;
 72             if(a[i][j]==2) dor[++dor[0]]=id[i][j];
 73         }
 74     mov[1][0]=0; mov[1][1]=1;
 75
 76     mov[2][0]=0; mov[2][1]=-1;
 77     mov[3][0]=1; mov[3][1]=0;
 78     mov[4][0]=-1;mov[4][1]=0;
 79     memset(dis,30,sizeof(dis));
 80     int x,y;
 81     for(int i=1;i<=dor[0];i++){
 82         find_short(dor[i]);
 83     }
 84 }
 85 bool nengpao(){
 86     for(int i=1;i<=n;i++){
 87         for(int j=1;j<=m;j++){
 88             bool ok=0;
 89             if(a[i][j]==0 || a[i][j]==2) continue;
 90             for(int k=1;k<=dor[0];k++){
 91                 if(dis[id[i][j]][dor[k]]<10000) ok=1;
 92             }
 93             if(!ok) return 0;
 94         }
 95     }
 96     return 1;
 97 }
 98 int dep[300010];
 99 bool BFS(){
100     //if(zhao==149) cout<<zhao<<endl;
101     memset(dep,0,sizeof(dep));
102     queue<int> q; int k;
103     dep[S]=1;
104     q.push(S);
105     while(!q.empty()){
106         k=q.front(); q.pop();
107         for(int i=adj[k];i!=-1;i=g[i].nxt){
108             int v=g[i].v;
109             if(g[i].w && !dep[v]){
110                 dep[v]=dep[k]+1;
111                 if(v==T) return 1;
112                 q.push(v);
113             }
114         }
115     }
116     return 0;
117 }
118 int dfs(int x,int fw){
119     //printf("x==%d   fw==%d\n",x,fw);
120     if(x==T) return fw;
121     int tmp=fw,k;
122     for(int i=adj[x];i!=-1;i=g[i].nxt){
123         int v=g[i].v;
124         if(g[i].w && tmp && dep[v]==dep[x]+1){
125             k=dfs(v,min(tmp,g[i].w));
126             if(!k){
127                 dep[v]=0;
128                 continue;
129             }
130             g[i].w-=k; g[i^1].w+=k; tmp-=k;
131         }
132     }
133     return fw-tmp;
134 }
135 bool check(int lim){
136     int ch=lim; zhao=lim;
137     memset(adj,-1,sizeof(adj)); e=0;
138     for(int i=1;i<=dor[0];i++){
139         for(int j=1;j<=lim;j++){
140             add((i-1)*ch+j+jia,T,1); add(T,(i-1)*ch+j+jia,0);
141         }
142     }
143     for(int i=1;i<=n;i++){
144         for(int j=1;j<=m;j++){
145             //cout<<"id2=="<<id[i][j]<<endl;
146             if(a[i][j]==0 || a[i][j]==2) continue;
147             //cout<<"id== "<<id[i][j]<<endl;
148             add(S,id[i][j],1); add(id[i][j],S,0);
149             for(int k=1;k<=dor[0];k++){
150                 if(dis[id[i][j]][dor[k]]>10000) continue;
151                 for(int hh=dis[id[i][j]][dor[k]];hh<=lim;hh++){
152                     add(id[i][j],(k-1)*ch+hh+jia,1), add((k-1)*ch+hh+jia,id[i][j],0);
153                     //if(lim==300) cout<<id[i][j]<<"   "<<(k-1)*ch+hh+jia<<endl;
154                 }
155             }
156         }
157     }
158     int he=0,tan;
159     while(BFS()){
160         while(tan=dfs(S,INF)){ he+=tan; }
161     }
162     //cout<<"lim== "<<lim<<"  "<<he<<endl;
163     if(he>=peo) return 1;
164     else return 0;
165
166 }
167 void work(){
168     S=0; T=300000;
169     int l=0,r=600,mid,ans=600;
170     while(l<=r){
171         mid=(l+r)>>1;
172         if(check(mid)) ans=mid,r=mid-1;
173         else l=mid+1;
174     }
175     printf("%d\n",ans);
176     return;
177 }
178 int main(){
179     //freopen("a.in","r",stdin);
180     //freopen("a.out","w",stdout);
181     init();
182     bool ok=nengpao();
183     if(!ok){
184         printf("impossible\n");
185         return 0;
186     }
187     work();
188     return 0;
189
190 }

转载于:https://www.cnblogs.com/FOXYY/p/7265883.html

[HNOI2007]紧急疏散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 spfa+网络流+二分

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

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

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

  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. 【HNOI2007】紧急疏散

    题面 题解 \(\text{HNOI2007}\)真的恐怖 这是集合了所罗门的咒语,胜负一子等神仙题和码农题的一年 所以这道题非常码 二分答案,将门拆点,于是就变成了一个二分图匹配的题目 反正很恶心 ...

  9. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1435  Solv ...

  10. [HNOI2007] 分裂游戏

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1460  Solved: 889 [Submit][Sta ...

最新文章

  1. 微信打开网址后自动调用手机自带默认浏览器或提示选择浏览器打开如何实现...
  2. hdu 1874 畅通工程续(模板题 spfa floyd)
  3. 硬件加速会使电脑黑屏吗?
  4. IT行业的职员加班到底有没有价值?
  5. 测量两台机器的的网络延迟和时间差
  6. [摘文]BizTalk概述
  7. java struts xml文件设置----自定义日期转换器(局部,及全局类型转换器类)
  8. 直播视频网站源码,延迟的几种方式
  9. Open browser failed!! Please check if you have installed the browser correctly! Alt + B无效 - VS Code
  10. 教学设计的理念与方法【2】
  11. 11.0.高等数学3-平面与直线的位置关系
  12. dnastar拼接反向互补序列_DNAstar使用说明
  13. 在线UML图设计 用例图 在线制图
  14. Qq也进入鸿蒙系统,鸿蒙系统完善进行中,手机QQ接入HMS不需要后台运行秒收信息...
  15. 学计算机有哪些推荐书籍?
  16. 如何使用百度baidu对某个特定网站进行站内搜索/检索
  17. 美团后台开发秋招面经汇总(更新至2021-08-13)
  18. Python爬虫(一):简单小说爬取实例
  19. 太赫兹成像系统行业调研报告 - 市场现状分析与发展前景预测
  20. ASP实现在线发送邮件

热门文章

  1. 已解决ModuleNotFoundError: No module named ‘frontend‘
  2. 如何测试app启动时间?
  3. “视”不可挡:征兵招警,近视手术成“通关法宝”
  4. 本地搭建wooyun图片无法加载问题解决
  5. 小程序与bmob后端云
  6. 步步高彭雄:弄潮“互联网+零售”从端到端流程开始
  7. android 充电模式deamon_它是首款无线充电手机,也是雷军十年前的最爱|极客博物馆...
  8. 实战开发支付SDK —— 对接微信支付看这一篇文章就够啦(含源码)
  9. 魔兽RPG仿魔兽世界:基尔加丹的末日V1.0
  10. 近两年ABSA相关ACL/EMNLP论文列表