紧急疏散evacuate
1689: [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 一道网络流的题:我们发现时间是满足单调性的,所以可以二分时间logn的复杂度,在当前时间限制下,将原点与每个人相连,每个人于能到达的不同时刻的每个门相连,意思是要将每个门拆点,拆成在不同时刻的门。所以要预处理出每个人到每个门的最短距离,跑一边dfs,再由这些门与汇点相连,这些边的容量为一;在这道题上炮最大流就行了,当且仅当最大流的数值等于总人数是,此时间点是可行的。
如果最终结果为你二分的上界的话:意思是没有这种情况,cout<<impossible;所以上界要定的稍大一些; 附代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define inf 5000000
map<pair<int,int>,int>ma;
int n,m,num,cnt,shu;
int pos[][],id[][],dis[][];
char s[][];int adj[];
struct flow{
int s,t,w,next;
}k[];
int read(){
int sum=;char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<=''){sum=sum*+ch-'';ch=getchar();}
return sum;
}
void dfs(int fa,int cnt,int x,int y){
if(pos[x-][y]==){
if(dis[fa][id[x-][y]]>dis[fa][cnt]+){
dis[fa][id[x-][y]]=dis[fa][cnt]+;
dfs(fa,id[x-][y],x-,y);
}
}
if(pos[x+][y]==){
if(dis[fa][id[x+][y]]>dis[fa][cnt]+){
dis[fa][id[x+][y]]=dis[fa][cnt]+;
dfs(fa,id[x+][y],x+,y);
}
}
if(pos[x][y-]==){
if(dis[fa][id[x][y-]]>dis[fa][cnt]+){
dis[fa][id[x][y-]]=dis[fa][cnt]+;
dfs(fa,id[x][y-],x,y-);
}
}
if(pos[x][y+]==){
if(dis[fa][id[x][y+]]>dis[fa][cnt]+){
dis[fa][id[x][y+]]=dis[fa][cnt]+;
dfs(fa,id[x][y+],x,y+);
}
}
}
void search(int x,int y){
dis[id[x][y]][id[x][y]]=;
dfs(id[x][y],id[x][y],x,y);
}
void init(int s,int t,int w){
k[num].s=s;k[num].t=t;k[num].w=w;
k[num].next=adj[s];adj[s]=num++;
}
void build(int lim){
num=;memset(adj,-,sizeof(adj));
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
if(pos[i][j]==)
init(,id[i][j],),init(id[i][j],,);
if(pos[i][j]==){
for(int u=;u<=lim;++u)
init(ma[make_pair(id[i][j],u)],,),init(,ma[make_pair(id[i][j],u)],);
for(int u=;u<=n;++u)
for(int p=;p<=m;++p)
if(pos[u][p]==)
for(int b=dis[id[i][j]][id[u][p]];b<=lim;++b)
init(id[u][p],ma[make_pair(id[i][j],b)],),init(ma[make_pair(id[i][j],b)],id[u][p],); }
}
}
int dp[];
bool bfs(){
memset(dp,,sizeof(dp));
queue<int>q;
q.push();dp[]=;
while(!q.empty()){
int o=q.front();q.pop();
for(int i=adj[o];i!=-;i=k[i].next){
if(!k[i].w||dp[k[i].t]) continue;
dp[k[i].t]=dp[o]+;
if(k[i].t==) return true;
q.push(k[i].t);
}
}
return false;
}
int Dfs(int o,int fw){
if(o==) return fw;
int tmp=fw,u;
for(int i=adj[o];i!=-;i=k[i].next){
if(!k[i].w||!tmp||dp[k[i].t]!=dp[o]+) continue;
u=Dfs(k[i].t,min(k[i].w,tmp));
if(!u){
dp[k[i].t]=;continue;
}
k[i].w-=u;k[i^].w+=u;tmp-=u;
}
return fw-tmp;
}
bool judge(int ti){
build(ti);
int ans=;
while(bfs())
ans+=Dfs(,inf);
if(ans==shu) return true;
else return false;
}
int erfen(int l,int r){
if(l==r) return l;
int mid=(l+r)>>;
if(judge(mid))
return erfen(l,mid);
else
return erfen(mid+,r);
}
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
n=read();m=read();
memset(adj,-,sizeof(adj));
memset(pos,0x3f,sizeof(pos));
memset(dis,0x3f,sizeof(dis));
for(int i=;i<=n;++i)
scanf("%s",s[i]);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(s[i][j-]=='D')
pos[i][j]=,id[i][j]=++cnt;
else if(s[i][j-]=='.')
pos[i][j]=,id[i][j]=++cnt,shu++;
cnt=n*m;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(pos[i][j]==)
for(int u=;u<=;++u)
ma[make_pair(id[i][j],u)]=++cnt;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(pos[i][j]==)
search(i,j);
int ans=erfen(,);
if(ans==) printf("impossible");
else printf("%d\n",ans);
return ;
}
紧急疏散evacuate的更多相关文章
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- BZOJ-1189 紧急疏散evacuate BFS预处理+最大流+二分判定+神建模!!
绝世污题,垃圾题,浪费我一整天青春! 1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1262 ...
- 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]所有点连边, 然后跑匈牙利 ...
- [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个点连边,流量 ...
- bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流
[HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3626 Solved: 1059[Submit][St ...
- 【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
随机推荐
- C语言程序设计(基础)- 第0次作业
亲爱的同学们,恭喜你成为一名大学生,我也很荣幸能够带大家一起学习大学的第一门专业基础课.还在军训的你,肯定对大学生活和计算机专业有着美好的憧憬,那么大学生活是什么样子的那?计算机专业应该怎么学习那?请 ...
- C语言函数2
一.PTA实验作业 6-3 使用函数判断完全平方数: 1. 本题PTA提交列表: 2. 设计思路: 3.本题调试过程碰到问题及PTA提交列表情况说明: 1.一开始考虑让输入值N去整除一个循环变量i,i ...
- 学号:201621123032 《Java程序设计》第4周学习总结
1:本周学习总结 1. 写出你认为本周学习中比较重要的知识点关键词 继承,多态,父类object,抽象类 2. 尝试使用思维导图将这些关键词组织起来 2:书面作业 2.1: 面向对象设计 1. 讲故事 ...
- scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250
scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250 前言 经过上一篇教程我们已经大致了解了Scrapy的基本情况,并写了一个简单的小demo.这次我会以爬取豆瓣电影TOP250为例进一步为大 ...
- android数据库持久化框架, ormlite框架,
前言 Android中内置了SQLite,但是对于数据库操作这块,非常的麻烦.其实可以试用第3方的数据库持久化框架对之进行结构上调整, 摆脱了访问数据库操作的细节,不用再去写复杂的SQL语句.虽然这样 ...
- CPP链表示例
#include<iostream> #include<stdlib.h> using namespace std; typedef struct Student_data { ...
- SourceTree 实现 git flow 流程
为什么使用 git 和 git flow,这篇文章 深入理解学习Git工作流 的内容相信能够给你一个完整的答案. 我们以使用SVN的工作流来使用git有什么不妥? git 方便的branch在哪里,团 ...
- 一句话了解JAVA与大数据之间的关系
大数据无疑是目前IT领域的最受关注的热词之一.几乎凡事都要挂上点大数据,否则就显得你OUT了.如果再找一个可以跟大数据并驾齐驱的IT热词,JAVA无疑是跟大数据并驾齐驱的一个词语.很多人在提到大数据的 ...
- python 字符串和字典
一.字符串操作 name = "my name is \t {name} and i am {year} years old" 1.首字母大写 print(name.capital ...
- NoSQL简介
相信大家也多多少少了解过一些数据库,最常用的当属MySQL了,当然也这是关系型数据库的代表了 常见的关系型数据库有:MySQL.SQLServer.Oracle 而数据库也有另一个流派-----NoS ...