P3191 [HNOI2007]紧急疏散EVACUATE

费用流+卡常优化

我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护

于是根据时间分层,到门的时候再计算代价,即代价$=$层数

每经过$1$单位时间就向下走一层

然后就是优化:

1. 删去多余点(层):只要开和人数相同的层,因为一个人的等待时间一定小等于人数

2. 能预处理的尽量预处理

3. register,快读,inline等

4. 能不用stl尽量不用(使用stl:queue=TLE),建议手写队列

复杂度$O($卡常能过$)$,详情可看code

#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
using namespace std;
#define N 200005
#define M 3000005
const int d1[]={,,,-};
const int d2[]={,,-,};
char a[][];
int n,m,nm,mx,ans,tot,S,T,v[N],p[N],id[][];
bool vis[N]; int h[M],L,R;
int Cnt=,hd[N],nxt[M],ed[N],poi[M],con[M],val[M];
void adde(int x,int y,int v1,int v2){
nxt[ed[x]]=++Cnt; hd[x]=hd[x]?hd[x]:Cnt;
ed[x]=Cnt; poi[Cnt]=y; con[Cnt]=v1; val[Cnt]=v2;
}
inline void link(int x,int y,int v1,int v2){adde(x,y,v1,v2),adde(y,x,,-v2);}
#define to poi[i]
bool bfs(){//普通费用流
memset(v,,sizeof(v)); int inf=v[];
h[L=]=S; R=; vis[S]=; v[S]=;
while(L!=R){
re int x=h[L++]; vis[x]=;
if(L>=M) L=;
for(re int i=hd[x];i;i=nxt[i])
if(con[i]&&v[to]>v[x]+val[i]){
v[to]=v[x]+val[i]; p[to]=i;
if(!vis[to]){
vis[to]=,h[R++]=to;
if(R>=M) R=;
}
}
}if(v[T]==inf) return ;
tot-=; ans=max(ans,v[T]);
for(re int u=T;u!=S;u=poi[p[u]^])
con[p[u]]-=,con[p[u]^]+=;
return ;
}//因为每次流量均为1,可以省去流量数组
void draw(int x,int y){
re int p=id[x][y];
if(a[x][y]=='X') return ;
if(a[x][y]=='D') for(re int i=;i<=mx;++i) link(p+i*nm,T,,i);//分层与终点连边,代价=层数
if(a[x][y]=='.'){
link(S,p,,); ++tot;
for(re int i=;i<mx;++i){
link(p+i*nm,p+(i+)*nm,1e9,);
for(re int j=;j<;++j){
int rx=x+d1[j],ry=y+d2[j];
if(a[rx][ry]=='X') continue;
link(p+i*nm,id[rx][ry]+(i+)*nm,1e9,);//与四周连边
}
}
}
}
int main(){
scanf("%d%d",&n,&m); S=N-; T=N-; nm=n*m;
for(re int i=;i<=n;++i) scanf("%s",a[i]+);
for(re int i=;i<=n;++i)
for(re int j=;j<=m;++j)
mx+=(a[i][j]=='.'),id[i][j]=(i-)*m+j;//mx:人数,建图需要的层数
for(re int i=;i<=n;++i) for(re int j=;j<=m;++j) draw(i,j);
while(bfs()) ;
if(tot) puts("impossible");
else printf("%d",ans);
return ;
}

P3191 [HNOI2007]紧急疏散EVACUATE(费用流)的更多相关文章

  1. P3191 [HNOI2007]紧急疏散EVACUATE

    传送门 这一题很容易想到网络流 一开始傻逼地模拟整个图每一个时间的情况,显然会爆炸 发现我们只要考虑起点到门之间的距离,不用每一步只走一格 所以直接 $BFS$ 预处理距离然后二分答案,网络流判断即可 ...

  2. 洛谷 P3191 [HNOI2007]紧急疏散EVACUATE(网络最大流)

    题解 二分答案+Dinic最大流 二分答案\(mid\) 把门拆成\(mid\)个时间点的门 相邻时间的门连一条\(inf\)的边 预处理出每个门到每个人的最短时间 为\(dis[k][i][j]\) ...

  3. BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)

    Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...

  4. 题解 P3191 [HNOI2007]紧急疏散EVACUATE

    题解 本篇题解做法为BFS+二分+最大流 二分需要撤离的时间,也就是答案(这算是一个比较套路的了) 重点在于建模(设时间为 \(tim\)): 我们将每个门拆点,拆成 \(tim\) 个,每个点向汇点 ...

  5. luogu P3191 [HNOI2007]紧急疏散EVACUATE

    传送门 qwq这题好大力 首先可以预处理出每个人到每个门前面那个格子的最早时间,然后答案如果比最小答案大的话也是合法的,所以可以二分最终答案.检查\(mid\)是否合法就考虑每个人要去哪个门才会合法, ...

  6. BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 412[Submi ...

  7. 【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE

    [HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...

  8. Bzoj1189 [HNOI2007]紧急疏散evacuate

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2293  Solved: 715 Descr ...

  9. [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)

    [HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...

随机推荐

  1. Jupyter Notebook 安装与使用

    Ref: https://jupyter.org/install Installing Jupyter Notebook with pip python -m pip install --upgrad ...

  2. [NOI2015]程序自动分析(并查集,离散化)

    [NOI2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表程序中出现的 ...

  3. Java List 类型转换

    java的类型转换让人忍不住在开始编码前骂一声  FUCK! 1  子类转父类 up List<SubClass> subs = ...; List<? extends BaseCl ...

  4. Windows中的Work线程和GUI线程

    Windows线程分为两种:Worker线程.GUI线程 worker线程:是指完全不牵扯到图形用户界面(GUI),纯粹做运算的线程. GUI线程:负责建造窗口以及处理消息循环(拥有消息队列).任何一 ...

  5. 【面试题】JavaScript

    第一题 合并 const a = { name: "zhangsan", age: 22 } const b = { name: "lisi", age: 55 ...

  6. HashMap的几种遍历方式(转载)

    今天讲解的主要是使用多种方式来实现遍历HashMap取出Key和value,首先在java中如果想让一个集合能够用for增强来实现迭代,那么此接口或类必须实现Iterable接口,那么Iterable ...

  7. MongoDB与阿里云达成战略合作,最新数据库独家上线阿里云!

    11月26日,开源数据库厂商MongoDB与阿里云在北京达成战略合作,作为合作的第一步,最新版MongoDB 4.2数据库产品正式上线阿里云平台. 目前阿里云成为全球唯一可提供最新版MongoDB服务 ...

  8. gawk进阶

    一.使用变量 gawk支持两种不同类型的变量: 内建变量 自定义变量 1.1 内建变量 ①字段和记录分隔符变量 FIELDWIDTHS:有空格分割的一列数字,定义了每个数据字段确切宽度 FS:输入字段 ...

  9. 20180711-Java Number类

    下面是一个装箱与拆箱的例子: public class Test{ public static void main(String args[]){ Integer x = 5; // boxes in ...

  10. [NOIP2016]蚯蚓 题解

    题目描述 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」= [3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. ...