bzoj1189/洛谷3191 [HNOI2007]紧急疏散evacuate【网络流】【二分答案】

[线性规划与网络流24题] 网络流常见模型 最近两个月在做《线性规划与网络流24题》这套题,加深了对网络流的理解。涵盖到的模型有:二分图匹配、二分图的最大独立集、最大权闭合图、有向无环图的最小路径覆盖、最多不相交路径、最大权不相交路径、区间k覆盖、最短路。第13题涉及到与二分法的结合(其实也可以逐层枚举)。二分图匹配设二分图G=(V, E)的两个顶点集为X, Y。 s->Xi,费用为0,按需赋容量。 Xi->Yj,(Xi, Yj)属于E,费用 阅读详情

题目描述

发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一块空地;如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。

输入输出格式

输入格式:

输入文件第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,以下N行M列描述一个N M的矩阵。其中的元素可为字符'.'、'X'和'D',且字符间无空格。

输出格式:

只有一个整数K,表示让所有人安全撤离的最短时间,如果不可能撤离,那么输出'impossible'(不包括引号)。

一开始网络流时直接将门与汇点建一条mid的边,WA了之后发现有些空位无法到达部分门,果然我还是太年轻。

应该将门按照时间拆成mid个点然后dinic判断最大流是否为人数。

上代码:

#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int xx[4]={0,1,0,-1},yy[4]={1,0,-1,0};
const int maxn=4e4+5,maxm=2e6+5,INF=0x3f3f3f3f;
char mp[25][25];
int N,M,S,T,ans,tot,sum,st,cnt,hed,til,L,R;
int son[maxm],nxt[maxm],flw[maxm],lnk[maxn],G[25][25];
int dep[maxn],cur[maxn],que[maxn],ed[maxn],dis[maxn][25][25];
inline char read() {
	char ch=getchar();
	while (ch!='X'&&ch!='.'&&ch!='D') ch=getchar();
	return ch;
}
inline bool bfs() {
	for (int i=0; i<=T; i++) cur[i]=lnk[i],dep[i]=-1;
	que[til=1]=S,hed=dep[S]=0;
	while (hed<til)
		for (int k=lnk[que[++hed]]; ~k; k=nxt[k]) if (dep[son[k]]<0&&flw[k]>0)
			dep[son[k]]=dep[que[hed]]+1,que[++til]=son[k];
	return dep[T]>0;
}
int dfs(int now,int flow) {
	if (now==T) return flow;
	for (int &k=cur[now]; ~k; k=nxt[k]) if (dep[son[k]]==dep[now]+1&&flw[k]) {
		int d=dfs(son[k],min(flow,flw[k]));
		if (d>0) {
			flw[k]-=d,flw[k^1]+=d;
			return d;
		}
	}
	return 0;
}
inline void add_edge(int x,int y,int z) {
	son[tot]=y,flw[tot]=z,nxt[tot]=lnk[x],lnk[x]=tot++;
	son[tot]=x,flw[tot]=0,nxt[tot]=lnk[y],lnk[y]=tot++;
}
inline bool check(int x) {
	S=0,T=maxn-1;
	memset(lnk,-1,sizeof lnk),tot=0;
	for (int i=1; i<=sum; i++) add_edge(S,i,1);
	for (int k=1; k<=cnt; k++)
		for (int i=0; i<N; i++)
			for (int j=0; j<M; j++) if (mp[i][j]=='.'&&dis[k][i][j]<=x)
				add_edge(G[i][j],(k-1)*x+sum+dis[k][i][j],1);
	for (int i=1; i<=cnt; i++)
		for (int j=1; j<=x; j++) {
			int tmp=(i-1)*x+sum;
			add_edge(tmp+j,T,1);
			if (j<x) add_edge(tmp+j,tmp+j+1,INF);
		}
	int ret=0;
	while (bfs()) while (int d=dfs(S,INF)) ret+=d;
	return ret==sum;
}
inline void pre(int id) {
	queue <int> Q;
	while (!Q.empty()) Q.pop();
	dis[id][ed[id]/M][ed[id]%M]=0;
	Q.push(ed[id]);
	while (!Q.empty()) {
		int now=Q.front(),x=now/M,y=now%M;
		Q.pop();
		for (int f=0; f<4; f++) {
			int l=x+xx[f],r=y+yy[f];
			if (l<0||r<0||l>=N||r>=M||mp[l][r]!='.') continue;
			if (dis[id][l][r]>dis[id][x][y]+1)
				dis[id][l][r]=dis[id][x][y]+1,Q.push(l*M+r);
		}
	}
}
int main() {
	memset(dis,63,sizeof dis);
	scanf("%d%d",&N,&M);
	for (int i=0; i<N; i++)
		for (int j=0; j<M; j++) {
			mp[i][j]=read();
			if (mp[i][j]=='D') ed[++cnt]=i*M+j;
			if (mp[i][j]=='.') G[i][j]=++sum;
		}
	for (int i=1; i<=cnt; i++) pre(i);
	L=1,R=N*M;
	if (!check(R)) {puts("impossible");return 0;}
	while (L<=R) {
		int mid=L+(R-L>>1);
		if (check(mid)) ans=mid,R=mid-1;
		else L=mid+1;
	}
	printf("%d\n",ans);
	return 0;
}

这是我造数据的代码,思路是造门的位置,然后bfs造空位:

#include<windows.h>
#include<bits/stdc++.h>
using namespace std;
const int xx[4]={0,1,0,-1},yy[4]={1,0,-1,0};
int N,M,mp[950][950],X[1000],Y[1000],tot,sum,hed,til;
struct point{int x,y;};
inline int random(int x) {
	return ((rand()<<16)+(rand()<<1)+(rand()&1))%x+1;
}
inline int bfs(int id,int sum) {
	queue <point> Q;
	while (!Q.empty()) Q.pop();
	point st;
	st.x=X[id],st.y=Y[id];
	Q.push(st);
	while (!Q.empty()) {
		if (sum<=0) break;
		point now=Q.front(),nxt;
		Q.pop();
		for (int f=0; f<4; f++) if (random(15)^1) {
			int l=now.x+xx[f],r=now.y+yy[f];
			if (l<2||r<2||l>=N||r>=M||mp[l][r]!=3) continue;
			sum--,mp[l][r]=1;
			nxt.x=l,nxt.y=r;
			Q.push(nxt);
		}
	}
}
int main() {
	freopen("OJ.in","w",stdout);
	srand(GetTickCount());
	N=20,M=20;
	tot=rand()%10+2;
	printf("%d %d\n",N,M);
	for (int i=1; i<=N; i++)
	for (int j=1; j<=M; j++) mp[i][j]=3;
	for (int i=1; i<=tot; i++) {
		int x=rand()%N+1,y=rand()%M+1;
		if (mp[x][y]==3) mp[x][y]=2,X[++sum]=x,Y[sum]=y;
	}
	for (int i=1; i<=tot; i++) bfs(i,rand()%70);
	for (int i=1; i<=N; i++,putchar('\n'))
	for (int j=1; j<=M; j++)
		switch (mp[i][j]) {
			case 1: putchar('.');break;
			case 2: putchar('D');break;
			case 3: putchar('X');break;
		}
	return 0;
}

【HNOI2007】紧急疏散EVACUATE BFS+二分答案+最大流 题目描述发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是’.’,那么表示这是一块空地;如果是’X’,那么表示这是一面墙,如果是’D’,那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有 阅读详情

相关推荐

消防应急照明和疏散指示系统

消防应急照明和疏散指示系统

[HNOI2007]紧急疏散EVACUATE

1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 SecMemory Limit: 128 MBSubmit: 3601Solved: 1054[Submit][Status][Discuss] Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一 块空地;如...

weixin_30492601的博客 99

人员疏散模型

基于netlogo的人员疏散模型源代码

bzoj1189&洛谷P3191: [HNOI2007]紧急疏散evacuate

1189: [HNOI2007]紧急疏散evacuateTime Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3635  Solved: 1063[Submit][Status][Discuss]Description发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一块空地;如果是'X',那么表示这是...

qq_41510496的博客 233

面向紧急疏散的群体仿真技术研究

硕士论文,关于群体仿真的,有参考价值,浙江大学 随着三维动画技术的发展以及硬件运算能力的提高,计算机群体仿真技术得较快的发展,在虚拟现实仿真的应用领域特别是消防安全、城市规划、建筑计等方面也发挥了巨大作。近年来,关于公共安全群体仿真方面的研究主要中在安全通道设计,群体规划与管理,以及紧急疏散仿真等方面。本文主要研究了面向紧急疏散的群体仿真相关技术,建立起了从建模到评价一套群体仿真系统。

应急疏散可视化仿真

应急疏散可视化仿真”是一套基于delta3d的全三维应急可视化疏散仿真平台。目标是使传统的应急指挥三维可视化。将基本功能和业务功能相结合形成统一的应急指挥演示平台。该平台三维引擎部分基于Delta3D,兼容层基于Qt平台,传感器模拟基于Java技术。形成传感器—>应急平台—>指挥员的一整套应急指挥过程形式.

最大流 紧急疏散evacuate

1689: [HNOI2007]紧急疏散evacuate 时间限制: 1 Sec  内存限制: 128 MB 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是".",那么表示这是一块空地;如果是"X",那么表示这是一面墙,如果是"D",那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初

蒟蒻QTY 576

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?.docx

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?

[HNOI2007]紧急疏散

二分+网络流判定 首先处理出每个人和门间的距离 二分时间,连边时把每个门拆成mid个,一个人能在mid时间内到达,他也可以在这等一会儿,那么这mid个门之间连边 如果可以在x的时间内到达,那么x~mid之间他都可以出去,所以门向门加一连边 奉上未AC代码千万别复制 # include <bits/stdc++.h> # define IL inline # def...

weixin_34194359的博客 192

为什么我把「大模型Clouder认证:基于百炼平台构建智能体应用」作为大模型学习的第一站?从 0 到拿证全流程经验分享

【摘要】作为一个刚拿下「大模型 Clouder 认证:基于百炼平台构建智能体应用」的过来人,想在开头就和大家聊聊这个认证的特殊意义 —— 在企业加速 AI 落地的今天,能用低代码快速构建智能体应用,已经成为 AI 从业者的核心竞争力。无论是企业微信客服提效、钉钉机器人自动化办公,还是网站智能助手升级,这些场景化能力正是当下数字化转型的刚需。

davidkorhenn的博客 1529

《遥感大模型生产级实战:从数据到决策的端到端AI工程》系列第三部分:城市洪涝灾害应急响应与评估平台实战-文章 14:项目二启动与多源异构数据对齐

我们将系统性地梳理城市洪涝场景下的所有关键数据源,从天上的卫星(光学与SAR)、空中的无人机,到地面的物联网传感器和社交媒体信息流,深入剖析每种数据在洪涝响应中的独特价值、获取方式与内在局限性。本章的核心将是一个详尽的、生产级的数据对齐技术全景,我们将分步解决三大核心对齐难题:空间对齐(将所有数据投影到统一的地理坐标系)、时间对齐(处理不同采样频率的时间序列)以及最困难的语义对齐(将文本描述与物理观测相关联)。

panshengwu的博客 2003

bzoj 1189 紧急疏散 网络流

二分答案,网络流判断 将每个门拆点,每个人连向每个门的dis~当前解 然后跑最大流,如果等于人数,即为可行解 #include #include #include #include #include #include #define pa pair #define N 405 #define inf 0x7fffffff using namespace std; int n,m,p,per=

Ren_Ivan的博客 694

LabVIEW QMH模板实战:从创建到错误处理的完整指南

本文提供LabVIEW QMH模板从创建到错误处理的完整实战指南。详细解析了队列消息处理器(QMH)作为LabVIEW核心设计模式如何实现任务解耦与异步通信,涵盖事件处理循环、消息处理循环的搭建、用户事件创建、队列引用管理、消息优先级控制以及健壮的错误处理机制,帮助开发者构建稳定、可维护的复杂应用程序。

white的博客 726

【笔记】网络流——从入门到疏散

网络流初步 参考资料:紫书11.4 最大流 想要把一些东西从s(源点)运到t(汇点),可以从中间节点中转。 对于一条边,物品上限称为容量ccc,实际运送的物品称为流量fff 基本性质: 容量限制:f(u,v)&amp;amp;amp;amp;amp;lt;=c(u,v)f(u,v)&amp;amp;amp;amp;amp;lt;=c(u,v)f(u,v)&amp;amp;amp;amp;lt;=c(u,v) 斜对称性:f(u,v)=−f(v,u)f(u,v)=-

秋叶红于二月花 614

Simulink玩转PMSM无感FOC:从IF强拖参数调试到切换失败的避坑指南

本文深入探讨了Simulink在PMSM无感FOC控制中的IF强拖启动参数调试与切换避坑技巧。通过详细解析强拖加速、速度维持和闭环切换三大阶段的设计逻辑,以及五个常见陷阱的解决方案,帮助工程师快速定位启动失败和切换震荡问题。文章还提供了典型故障的波形诊断方法和高级调试工具链优化建议,是电机控制领域的实用指南。

weixin_29164843的博客 408

从零开始安装pytorch(包含GPU和CPU版本的安装)

Pytorch是。

qiaoxinyu1989的博客 8万+

[HNOI2007] 紧急疏散EVACUATE

题目描述: 打死也不会想网络流的网络流题目. 题目分析: 07年的网络流都这难吗qwq 首先我们用BFS求出每个空地到每扇门的时间. 二分时间 如果空地-&gt;门的时间&lt;=二分时间 空地-&gt;门连一条容量为1的边 S-&gt;每个空地连一条容量为1的边 对于每个门,我们拆成二分时间个点. 当前时间点门-&gt;T连一条容量为1的边,表示单位时间内门只能跑出去一个人...

HT008的Blog 266

光模块的封装工艺有哪些?

COB封装传统的单路10Gb/s或25Gb/s速率的光模块采用SFP封装将电芯片和TO封装的光收发组件焊接到PCB板上组成光模块。但对于40G及以上速率的高速光模块,受激光器速率限制(多为25G),主要通过多通道并行实现,如40G由4×10G实现,而100G则由4×25G实现。蝶形封装:壳体通常为长方体,结构及实现功能通常比较复杂,可以内置制冷器、热沉、陶瓷基块、芯片、热敏电阻、背光监控,并且可以支持所有以上部件的键合引线。BOX封装属于蝶形封装的一种,用于多通道并行封装。

WaytoICT- Explore ICT Technology, Build Your Tech Path 3810

【HNOI2007】bzoj1189 紧急疏散

二分答案+最大流

YHaX的博客 457

喷涂机器人系列编程:ABB IRB 5500_(9).常见故障诊断与排除

ABB IRB 5500 喷涂机器人在实际应用中可能会遇到各种故障,但通过系统的诊断和排除方法,可以确保生产线的连续运行。定期维护和保养是预防故障的重要手段,而操作培训和规范则能有效减少人为因素引起的故障。希望本节内容能帮助操作和维护人员提高故障诊断和排除的效率,确保喷涂机器人的稳定运行。如果您有任何疑问或需要进一步的帮助,请联系 ABB 客户服务中心。

zhubeibei168的博客 1045

可疑物品遗留检测系统:基于YOLOv8的智能安防解决方案

数据采集与标注模块:负责收集和标注可疑物品图像数据模型训练模块:基于YOLOv8算法训练检测模型推理检测模块:加载训练好的模型进行实时检测用户界面模块:提供友好的操作界面和可视化结果展示报警模块:当检测到可疑物品时触发报警机制:包含多种暴力场景和可疑物品SUAVe:监控场景下的异常行为与物品数据集:包含多种可疑物品自建数据集:针对特定场景收集的数据背包(backpack)手提箱(suitcase)无人看管的包裹(package)可疑箱子(box)

YOLO 435

网络流一般化建模方式/最大流篇

最大流模板 分配类型问题: 将物资均匀分配到多个点上。 典型例子:网络流24题圆桌问题/试题库问题/分配问题 一般化建模方式:将每个可分配的点连上源点,容量为可分配流量数;将每个待分配的点连上汇点,容量为待分配流量数; 点之间按题目关系连边,容量按题目而定(1或者inf),最大流即可。 例题: 【tyvj1431】分配任务 随着tyvj发展越来越大,管理员的任务越来越重,如何合理的

CDQZOIERS的博客 2409

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【bzoj1189】[HNOI2007]紧急疏散evacuate

*题目描述: 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是’.’,那么表示这是一块空地;如果是’X’,那么表示这是一面墙,如果是’D’,那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏...

diaopinshuo4087的博客 143

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

洛谷P3425 【网络流】【二分答案】[POI2005]KOS-Dicing

【题目描述】 KOS-Dicing 题解:二分+网络流 看到"最大值最小",显然要二分最少赢多少场。 源点向每一个比赛连一条流量为1的边,表明每个比赛只能赢一次 每个比赛向2位选手各连一条流量为1的边,表明每个比赛只能有一个人赢 最后每个选手向汇点连一条流量为mid的边,如果总流量>=比赛数,那么这个做法可行 等等,要输出方案! 每一个比赛向哪一个选手连的边流量是1,就代表这个选手赢了 好...

qq_42754826的博客 281

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: POJ 1113(Wall)【凸包】
下一篇: [SCOI2008]着色方案 bzoj1079/洛谷2476
ZXfoil
博客等级 码龄9年 29粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值