【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE
[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 试题分析:创建超级源S,超级汇T
方便起见,先对于每一块空地BFS求出它到每个能到达的门的距离
然后二分答案,建图。
S连到每一个节点,容量为1的边。代表每个位置上有一个人。
简单粗暴的建图方法就是直接对于每个点将其每个时刻的点都建出来,会T一个点。
考虑优化,发现我们不用管每个时刻这个门的状态是什么,而是只用关心最后从这个门出去多少个。
所以我们的建图方法如下:
①S连接到每一块空地容量为1
②每一块空地连接到其在二分答案时间内可以到的门,容量为1
③将每一个门连向T,容量为X(二分的时间)
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
#define LL long long
const int MAXN = 500001;
const int MAXN2 = 1000001;
const int INF = 9999999; int N,M;
int Root[MAXN2+1],Next[MAXN2+1],Node[MAXN+1],C[MAXN2+1];
int cnt;
char Map[21][21]; void insert(int u,int v,int w){
C[cnt]=w; Node[cnt]=v;
Next[cnt]=Root[u]; Root[u]=cnt++;
return ;
}
struct data{
int x,y,tm;
};
bool vis[21][21];
int dis[21][21][21][21];
int dist[5][2]={{0,-1},{0,1},{1,0},{-1,0}};
int ans; int S,T,KT;
void BFST(){
data t;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
if(Map[i][j]=='.'){
++KT;
queue<data> Que;
t.x=i; t.y=j; t.tm=0;
Que.push(t);
memset(vis,0,sizeof(vis)); vis[i][j]=true;
while(!Que.empty()){
data k=Que.front(); Que.pop();
if(Map[k.x][k.y]=='D'){
dis[i][j][k.x][k.y]=k.tm;
continue;
}
for(int l=0;l<4;l++){
int xx=k.x+dist[l][0];
int yy=k.y+dist[l][1];
if(xx<1||yy<1||xx>N||yy>M||Map[xx][yy]=='X'||vis[xx][yy]) continue;
t.x=xx; t.y=yy; t.tm=k.tm+1;
vis[xx][yy]=true;
Que.push(t);
}
}
}
}
}
return ;
}
int D[MAXN+1];
bool BFS(){
queue<int> Que; Que.push(S);
memset(D,0,sizeof(D)); D[S]=1;
while(!Que.empty()){
int k=Que.front(); Que.pop();
for(int x=Root[k];x>-1;x=Next[x]){
int v=Node[x];
if(C[x]>0&&!D[v]){
D[v]=D[k]+1;
if(v==T) return true;
Que.push(v);
}
}
}
return false;
}
int cur[MAXN+1];
int DFS(int k,int t){
if(k==T) return t;
int res=0;
for(int x=cur[k];x>-1;x=Next[x]){
int v=Node[x];
if(C[x]>0&&D[v]==D[k]+1){
int tmp=DFS(v,min(C[x],t));
if(!tmp) continue;
C[x]-=tmp; t-=tmp; C[x^1]+=tmp; res+=tmp;
if(!t) return res;
}
cur[k]=x;
}
if(!res) D[k]=-1;
return res;
}
bool check(int K){
cnt=0;
for(int i=0;i<=MAXN;i++) Root[i]=-1;
memset(Next,0,sizeof(Next)); S=0,T=500000;
memset(C,0,sizeof(C)); memset(Node,0,sizeof(Node));
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
if(Map[i][j]=='.'){
insert(S,(i-1)*M+j,1);
insert((i-1)*M+j,S,0);
for(int l1=1;l1<=N;l1++){
for(int l2=1;l2<=M;l2++){
if(Map[l1][l2]=='D'&&dis[i][j][l1][l2]&&dis[i][j][l1][l2]<=K){
insert((i-1)*M+j,(l1-1)*M+l2,1);
insert((l1-1)*M+l2,(i-1)*M+j,0);
}
}
}
}
else if(Map[i][j]=='D'){
insert((i-1)*M+j,T,K);
insert(T,(i-1)*M+j,0);
}
}
}
int ans=0; --cnt;
while(BFS()){
for(int i=0;i<=N*M;i++) cur[i]=Root[i];
ans+=DFS(S,INF);
}
return ans>=KT;
} int main(){
N=read(),M=read();
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++)
cin>>Map[i][j];
}
BFST();
int l=0,r=400;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
if(ans) printf("%d\n",ans);
else puts("impossible");
}
【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE的更多相关文章
- BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1132 Solved: 412[Submi ...
- BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )
我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...
- bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流
[HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3626 Solved: 1059[Submit][St ...
- P3191 [HNOI2007]紧急疏散EVACUATE(费用流)
P3191 [HNOI2007]紧急疏散EVACUATE 费用流+卡常优化 我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护 于是根据时间分层,到门的时候再计算代价,即代价$=$层数 每经 ...
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- AC日记——[HNOI2007]紧急疏散evacuate bzoj 1189
[HNOI2007]紧急疏散evacuate 思路: 处理每个人到门的最短路: 然后二分答案: s向人连边流量1: 人向门拆分后的点连边流量1(拆成400,前一个点连当前点流量INF): 然后门向t连 ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
随机推荐
- Spring Boot 中使用 MyBatis 整合 Druid 多数据源
2017 年 10 月 20 日 Spring Boot 中使用 MyBatis 整合 Druid 多数据源 本文将讲述 spring boot + mybatis + druid 多数据源配置方 ...
- springboot:Spring boot中mongodb的使用(山东数漫江湖)
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...
- MongoDB 数据库(1)
数据库 MongoDB (芒果数据库) 数据存储阶段 文件管理阶段 (.txt .doc .xls) 优点 : 数据可以长期保存 可以存储大量的数据 使用简单 缺点 : 数据一致性差 数据查找修改不方 ...
- bzoj 2733 平衡树启发式合并
首先对于一个连通块中,询问我们可以直接用平衡树来求出排名,那么我们可以用并查集来维护各个块中的连通情况,对于合并两个平衡树,我们可以暴力的将size小的平衡树中的所有节点删掉,然后加入大的平衡树中,因 ...
- vue手势解决方案
1.需求 因为项目中要做一个可以移动.旋转和放缩具有合成图片的功能,例如: 剑可以随意移动,然后把位移.旋转角度和放缩值传给后台进行合成. 2.解决方案 网上搜到手势插件AlloyFinger,htt ...
- Pythone3 sys模块
1.sys.argv 可以实现从程序外部向程序传递参数2.sys.exit() 程序中间退出,exit(0)正常退出,其他为异常退出3.sys.getdefaultencoding() 获取系统编码方 ...
- 【设计模式】享元模式(Flyweight)
摘要: 1.本文将详细介绍享元模式的原理和实际代码中特别是Android系统代码中的应用. 纲要: 1. 引入享元模式 2. 享元模式的概念及优缺点介绍 3. 享元模式在Android源码中的应用 1 ...
- 辨别苹果数据线真伪 苹果计算器 Dashboard 知识
辨别苹果数据线真伪 苹果计算器 Dashboard 知识 苹果数据线真伪的最简单的辨别: 线质柔软 用数据线连接适配器(苹果自带的适配器)充电 连接手机 如果该手机数据线是假的, 在手机上会提示”该 ...
- popup menu案例,无说明只代码
效果图: 布局文件, 展示列表的容器 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- shell常见操作整理(更新)
查看文件第20到30行的内容 法一:[root@oldboy ~]# seq 100 > ett.txt [root@oldboy ~]# head -30 ett.txt | tail -11 ...