[bzoj1189]紧急疏散
二分答案+判定,对于一个答案,源点向每一个点连一条流量为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]紧急疏散的更多相关文章
- BZOJ-1189 紧急疏散evacuate BFS预处理+最大流+二分判定+神建模!!
绝世污题,垃圾题,浪费我一整天青春! 1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1262 ...
- 【BZOJ1189】紧急疏散(二分答案,最大流)
[BZOJ1189]紧急疏散(二分答案,最大流) 题面 Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是 ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1132 Solved: 412[Submi ...
- BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- bzoj1189 [HNOI2007]紧急疏散
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一 ...
- 【bzoj1189】[HNOI2007]紧急疏散evacuate BFS最短路+动态加边网络流
题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以 ...
随机推荐
- Java-多态(上)
什么是多态 同一方法可以根据发送对象的不同而采取多种不同的行为方式 一个对象实际类型是确定的 但指向其引用类型却有很多 注意事项 多态是方法的多态 属性没有多态 父类和子类 有联系 类型转换异常 Cl ...
- Centos7 python3环境搭建 兼容python2.7
Centos7 python3环境搭建 兼容python2.7 安装前提依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-devel ...
- Mysql双主双从高可用集群的搭建且与MyCat进行整合
1.概述 老话说的好:瞻前顾后.患得患失只会让我们失败,下定决心,干就完了. 言归正传,之前我们聊了Mysql的一主一从读写分离集群的搭建,虽然一主一从或一主多从集群解决了并发读的问题,但由于主节点只 ...
- Python中pymongo find 遍历数据导致timeout
背景 在读取大约200W左右的数据的时候采用游标形式进行数据遍历时,超过10分钟就报错 timeout 原因 pymongo游标会在10分钟之后被关闭 解决方案 db.find({}, no_curs ...
- TCP 粘包 - 拆包问题及解决方案
目录 TCP粘包拆包问题 什么是粘包 - 拆包问题 为什么存在粘包 - 拆包问题 粘包 - 拆包 演示 粘包 - 拆包 解决方案 方式一: 固定缓冲区大小 方式二: 封装请求协议 方式三: 特殊字符结 ...
- leetcode 5/300 最长回文子串 py
目录 题目说明 方法一:动态规划--状态转移方程 方法二:优化中心扩展算法 题目说明 要看明白求得是什么,最长回文字串是指例如cababa中ababa是最长的,不是求回文的部分aba 方法一:动态规划 ...
- 攻防世界 杂项 4.something_in_image
这是原题 我这里使用编辑器打开,一看乱码也挺多的,于是想了想ctrl+f搜索一下flag关键字吧,结果答案出来了(flag不少,多搜索几次) Flag{yc4pl0fvjs2k1t7T}
- Spring Security 的注册登录流程
Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...
- 按之字形顺序打印二叉树 牛客网 剑指Offer
按之字形顺序打印二叉树 牛客网 剑指Offer 题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推 ...
- Ubuntu 16.04 curl 安装 使用
curl是利用URL语法在命令行方式显工作的开元文件传输工具. 安装 $ sudo apt install -y curl 使用 $ curl http://www.baidu.com 这是最简单的使 ...