BZOJ1189 [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
题解
先bfs预处理每个点到各个出口的最短距离
二分一下时间\(t\),对出口拆点表示各个时间的出口
每个人向每个出口大于最短路的那些点连边
然后网络流判一下能否完全匹配即可
【坑点:角落的出口无法到达】
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 300005,maxm = 6000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
char s[25][25];
int N,M,vis[25][25],id[25][25],now,X[] = {0,0,-1,1},Y[] = {-1,1,0,0};
int n,m,dis[405][405],flag,S,T;
int h[maxn],ne = 2;
struct EDGE{int to,nxt,f;}ed[maxm];
inline void build(int u,int v,int f){
ed[ne] = (EDGE){v,h[u],f}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v],0}; h[v] = ne++;
}
struct point{int x,y,d;};
void bfs(int x,int y){
memset(vis,0,sizeof(vis));
queue<point> q; q.push((point){x,y,0});
point u; int nx,ny;
while (!q.empty()){
u = q.front(); q.pop();
for (int k = 0; k < 4; k++){
nx = u.x + X[k];
ny = u.y + Y[k];
if (nx < 1 || ny < 1 || nx > N || ny > M || s[nx][ny] == 'X' || vis[nx][ny])
continue;
vis[nx][ny] = true;
if (s[nx][ny] == 'D') dis[id[x][y]][id[nx][ny]] = u.d + 1,flag = true;
else q.push((point){nx,ny,u.d + 1});
}
}
}
int q[maxn],head,tail;
int d[maxn],Vis[maxn],cur[maxn];
bool bfs(){
for (int i = S; i <= T; i++) d[i] = Vis[i] = 0;
q[head = tail = 1] = S; Vis[S] = true;
int u;
while (head <= tail){
u = q[head++];
Redge(u) if (ed[k].f && !Vis[to = ed[k].to]){
d[to] = d[u] + 1; Vis[to] = true;
if (to == T) return true;
q[++tail] = to;
}
}
return Vis[T];
}
int dfs(int u,int minf){
if (u == T || !minf) return minf;
int flow = 0,f,to;
if (cur[u] == -1) cur[u] = h[u];
for (int& k = cur[u]; k; k = ed[k].nxt)
if (d[to = ed[k].to] == d[u] + 1 && (f = dfs(to,min(minf,ed[k].f)))){
ed[k].f -= f; ed[k ^ 1].f += f;
flow += f; minf -= f;
if (!minf) break;
}
return flow;
}
int maxflow(){
int flow = 0;
while (bfs()){
for (int i = S; i <= T; i++) cur[i] = -1;
flow += dfs(S,INF);
}
return flow;
}
bool check(int len){
memset(h,0,sizeof(h));
ne = 2; S = 0; T = n + m * len + 1;
REP(i,n){
build(S,i,1);
REP(j,m){
for (int k = dis[i][j]; k <= len; k++)
build(i,n + (j - 1) * len + k,1);
}
}
REP(i,m) REP(j,len) build(n + (i - 1) * len + j,T,1);
int t = maxflow();
return t == n;
}
int main(){
N = read(); M = read();
REP(i,N){
scanf("%s",s[i] + 1);
REP(j,M){
if (s[i][j] == '.') id[i][j] = ++n;
if (s[i][j] == 'D') id[i][j] = ++m;
}
}
REP(i,n) REP(j,m) dis[i][j] = INF;
REP(i,N) REP(j,M){
if (s[i][j] == '.'){
flag = false;
bfs(i,j);
if (!flag) {
puts("impossible");
return 0;
}
}
}
int l = 0,r = 500,mid;
while (l < r){
mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n",l);
return 0;
}
BZOJ1189 [HNOI2007]紧急疏散evacuate 【二分 + 网络流】的更多相关文章
- bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流
[HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3626 Solved: 1059[Submit][St ...
- 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',那么表示这是 ...
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
[法一]枚举Time(0~N*M): S->'.'(1); 'D'->T(Time); '.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意di ...
- BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
- BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )
我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...
随机推荐
- 2018.5.9 Oracle数据库查询命令
0.查询所有数据(最简单,但是时间很久) select * from emp; Result: EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- - ...
- centos7-vsftpd文件服务器
FTP简介: 文件传输协议(File Transfer Protocol,FTP),基于该协议FTP客户端与服务端可以实现共享文件.上传文件.下载文件. FTP 基于TCP协议生成一个虚拟的连接,主要 ...
- C++中malloc / free 和 new / delete 的区别?
1.malloc/free 是C++/C语言的标准库函数,New/delete是C++运算符:都是用于申请动态内存和释放内存. 2.new做两件事:分配内存和调用类的构造函数,delete是:调用类的 ...
- NIOP 膜你题
NOIp膜你题 Day1 duliu 出题人:ZAY 1.大美江湖(mzq.cpp/c) [题目背景] 细雪飘落长街,枫叶红透又一年不只为故友流连,其实我也恋长安听门外足音慢,依稀见旧时容颜 ...
- 设置通过Maven创建的工程的JDK的版本,更改conf/settings.xml
eclipse提示警告如下: Build path specifies execution environment J2SE-1.5. There are no JREs installed in t ...
- 【数学 BSGS】bzoj2242: [SDOI2011]计算器
数论的板子集合…… Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最 ...
- python入门:输出1-10以内除去7的所有数(自写)
#!/usr/bin/env python # -*- coding:utf-8 -*- #输出1-10以内除去7的所有数(自写) """ 变量kaishi赋值等于1,w ...
- vue 配置多页面应用
前言: 本文基于vue 2.5.2, webpack 3.6.0(配置多页面原理类似,实现方法各有千秋,可根据需要进行定制化) vue 是单页面应用.但是在做大型项目时,单页面往往无法满足我们的需求, ...
- ASP.NET Web网站中App_Code文件夹的作用及使用场景
原文地址:Web Site项目和ASP.NET Web Application中App_Code文件夹的作用作者:宾的宾 我现在要建一个ASP.NET的网站了,不难吧,开始动手.如下图: 这种方法建立 ...
- 字符串-POJ3974-Palindrome
Palindrome Time Limit: 15000MS Memory Limit: 65536K Description Andy the smart computer science stud ...