二分答案+判定,对于一个答案,源点向每一个点连一条流量为1的边,每一扇门向汇点连一条流量为时间的边,每一个人向每一个在答案时间内能走到的门连一条流量为1的边,跑最大流并判断流量是否等于人数。

然而自从bzoj新增数据后就跑不过了,原因是不能保证有一组最优撤离方案使得在最后一个时刻以前(最后一个时刻可能人不够),每一扇门每一个时刻都有人出去(具体数据见bzoj讨论板)。

可以对门拆为时间个点,每一个点向它到某扇门的最早时间以后每一个时刻的门连一条流量为1的边,每一个门现在只有1的流量,再跑网络流即可(只要开40000个点和5000000条边即可,当然最坏的点数/边数要比这个大)。

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 50005
4 #define id i*m+j+1
5 struct ji{
6 int nex,to,len;
7 }edge[N*100];
8 queue<int>q;
9 int E,T,n,m,pe,head[N],work[N],d[N],vis[405][405],bh[405][41];
10 char s[31][31];
11 void add(int x,int y,int z){
12 edge[E].nex=head[x];
13 edge[E].to=y;
14 edge[E].len=z;
15 head[x]=E++;
16 if (E&1)add(y,x,0);
17 }
18 bool bfs(int k){
19 memset(d,-1,sizeof(d));
20 q.push(k);
21 d[k]=0;
22 while (!q.empty()){
23 k=q.front();
24 q.pop();
25 for(int i=head[k];i!=-1;i=edge[i].nex)
26 if ((edge[i].len)&&(d[edge[i].to]<0)){
27 d[edge[i].to]=d[k]+1;
28 q.push(edge[i].to);
29 }
30 }
31 return d[T]>=0;
32 }
33 int dfs(int k,int s){
34 if (k==T)return s;
35 for(int &i=work[k];i!=-1;i=edge[i].nex)
36 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
37 int p=dfs(edge[i].to,min(s,edge[i].len));
38 if (p){
39 edge[i].len-=p;
40 edge[i^1].len+=p;
41 return p;
42 }
43 }
44 return 0;
45 }
46 int dinic(){
47 int k,ans=0;
48 while (bfs(0)){
49 memcpy(work,head,sizeof(head));
50 while (k=dfs(0,0x3f3f3f3f))ans+=k;
51 }
52 return ans;
53 }
54 bool pd(int mid){
55 memset(head,-1,sizeof(head));
56 E=0;
57 for(int i=0;i<n;i++)
58 for(int j=0;j<m;j++){
59 if (s[i][j]=='.'){
60 add(0,id,1);
61 for(int k=0;k<n*m;k++)
62 if (s[k/m][k%m]=='D')
63 for(int l=vis[id][k];l<=mid;l++)add(id,bh[k+1][l],1);
64 }
65 if (s[i][j]=='D')
66 for(int k=1;k<=mid;k++)add(bh[id][k],T,1);
67 }
68 return dinic()==pe;
69 }
70 int main(){
71 scanf("%d%d",&n,&m);
72 memset(head,-1,sizeof(head));
73 for(int i=0;i<n;i++)scanf("%s",s[i]);
74 for(int i=0;i<n;i++)
75 for(int j=0;j<m;j++)
76 if (s[i][j]!='X'){
77 if ((j)&&(s[i][j-1]!='X')&&((s[i][j-1]!='D')||(s[i][j]!='D')))add(id,id-1,1);
78 if ((j<m-1)&&(s[i][j+1]!='X')&&((s[i][j+1]!='D')||(s[i][j]!='D')))add(id,id+1,1);
79 if ((i)&&(s[i-1][j]!='X')&&((s[i-1][j]!='D')||(s[i][j]!='D')))add(id,id-m,1);
80 if ((i<n-1)&&(s[i+1][j]!='X')&&((s[i+1][j]!='D')||(s[i][j]!='D')))add(id,id+m,1);
81 }
82 for(int i=0;i<n;i++)
83 for(int j=0;j<m;j++)
84 if (s[i][j]=='.'){
85 bfs(id);
86 pe++;
87 for(int k=1;k<=n*m;k++)
88 if (d[k]==-1)vis[id][k-1]=10000;
89 else vis[id][k-1]=d[k];
90 }
91 T=n*m+1;
92 for(int i=0;i<n;i++)
93 for(int j=0;j<m;j++)
94 if (s[i][j]=='D')
95 for(int k=1;k<=pe;k++)bh[id][k]=T++;
96 int l=0,r=pe+1;
97 while (l<r){
98 int mid=(l+r>>1);
99 if (pd(mid))r=mid;
100 else l=mid+1;
101 }
102 if (l>pe)printf("impossible");
103 else printf("%d",l);
104 }

[bzoj1189]紧急疏散的更多相关文章

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

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

  2. 【BZOJ1189】紧急疏散(二分答案,最大流)

    [BZOJ1189]紧急疏散(二分答案,最大流) 题面 Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是 ...

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

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

  4. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

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

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

  6. BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)

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

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

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

  8. bzoj1189 [HNOI2007]紧急疏散

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

  9. 【bzoj1189】[HNOI2007]紧急疏散evacuate BFS最短路+动态加边网络流

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

随机推荐

  1. dg create datafile auto failed 排除处理

    1.Environment:11.2.0.4 dg 2.Symptoms:告警描述:Wed Sep 22 14:29:15 2021Errors in file /data/app/oracle/di ...

  2. SpringBoot 如何进行限流?老鸟们都这么玩的!

    大家好,我是飘渺.SpringBoot老鸟系列的文章已经写了四篇,每篇的阅读反响都还不错,那今天继续给大家带来老鸟系列的第五篇,来聊聊在SpringBoot项目中如何对接口进行限流,有哪些常见的限流算 ...

  3. iOS实现XMPP通讯(一)搭建Openfire

    安装Openfire Openfire官网下载地址:https://igniterealtime.org/downloads/ (也是Spark客户端的下载地址) Openfire下载并安装后,打开系 ...

  4. 题解 Yet Another Number Sequence

    题目传送门 Description 给出 \(n,k\) ,求出: \[\sum_{i=1}^{n} f_i·i^k \] 其中 \(f_i\) 表示斐波拉契第 \(i\) 项.\(n\le 10^{ ...

  5. WeakMap与Map,使用WeakMap实现深拷贝循环引用问题

    1.Map可以使用任意类型的key值,不限字符串,对象等. 2.WeakMap只能使用对象作为key值,是弱引用,当从WeakMap中移除时,会自动垃圾回收 3.Object只能用基本类型作为key值 ...

  6. [对对子队]会议记录4.19(Scrum Meeting10)

    今天已完成的工作 何瑞 ​ 工作内容:搭建第2关,基本完成第3关 ​ 相关issue:搭建关卡2.3 ​ 相关签入:4.19签入1 4.19签入2 刘子航 ​ 工作内容:完成关卡选择界面的设计图 ​ ...

  7. IDEA注释设置:从当前鼠标位置开始注释快捷键

    在写xml或html注释时,经常出现注释出来的时候都是顶格的,前面包含一大段空格,并没有在鼠标位置开始. 可在设置中进行修改,其他代码格式修改方法类似

  8. cURL 命令获取本机外网 IP

    1.1 查询本机外网 IP # curl dhcp.cn 134.175.159.160 1.2 输出格式为 JSON # curl dhcp.cn/?json { "IP": & ...

  9. HTML+CSS基础(HTML篇)

    引言 在日常开发Android中,很多时候会遇到和WebView打交道,对CSS HTML JS不是很清楚的话是完不成一些功能的,本篇开始学习HTML,文章的主要内容是总结了慕课网中,HTML+CSS ...

  10. OpenWrt编译问题记录

    错误一.config.status: error: cannot find input file: `xmetadataretriever/Makefile.in' configure: creati ...