P3191 [HNOI2007]紧急疏散EVACUATE

费用流+卡常优化

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

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

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

然后就是优化:

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

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

3. register,快读,inline等

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

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

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #define re register
  5. using namespace std;
  6. #define N 200005
  7. #define M 3000005
  8. const int d1[]={,,,-};
  9. const int d2[]={,,-,};
  10. char a[][];
  11. int n,m,nm,mx,ans,tot,S,T,v[N],p[N],id[][];
  12. bool vis[N]; int h[M],L,R;
  13. int Cnt=,hd[N],nxt[M],ed[N],poi[M],con[M],val[M];
  14. void adde(int x,int y,int v1,int v2){
  15. nxt[ed[x]]=++Cnt; hd[x]=hd[x]?hd[x]:Cnt;
  16. ed[x]=Cnt; poi[Cnt]=y; con[Cnt]=v1; val[Cnt]=v2;
  17. }
  18. inline void link(int x,int y,int v1,int v2){adde(x,y,v1,v2),adde(y,x,,-v2);}
  19. #define to poi[i]
  20. bool bfs(){//普通费用流
  21. memset(v,,sizeof(v)); int inf=v[];
  22. h[L=]=S; R=; vis[S]=; v[S]=;
  23. while(L!=R){
  24. re int x=h[L++]; vis[x]=;
  25. if(L>=M) L=;
  26. for(re int i=hd[x];i;i=nxt[i])
  27. if(con[i]&&v[to]>v[x]+val[i]){
  28. v[to]=v[x]+val[i]; p[to]=i;
  29. if(!vis[to]){
  30. vis[to]=,h[R++]=to;
  31. if(R>=M) R=;
  32. }
  33. }
  34. }if(v[T]==inf) return ;
  35. tot-=; ans=max(ans,v[T]);
  36. for(re int u=T;u!=S;u=poi[p[u]^])
  37. con[p[u]]-=,con[p[u]^]+=;
  38. return ;
  39. }//因为每次流量均为1,可以省去流量数组
  40. void draw(int x,int y){
  41. re int p=id[x][y];
  42. if(a[x][y]=='X') return ;
  43. if(a[x][y]=='D') for(re int i=;i<=mx;++i) link(p+i*nm,T,,i);//分层与终点连边,代价=层数
  44. if(a[x][y]=='.'){
  45. link(S,p,,); ++tot;
  46. for(re int i=;i<mx;++i){
  47. link(p+i*nm,p+(i+)*nm,1e9,);
  48. for(re int j=;j<;++j){
  49. int rx=x+d1[j],ry=y+d2[j];
  50. if(a[rx][ry]=='X') continue;
  51. link(p+i*nm,id[rx][ry]+(i+)*nm,1e9,);//与四周连边
  52. }
  53. }
  54. }
  55. }
  56. int main(){
  57. scanf("%d%d",&n,&m); S=N-; T=N-; nm=n*m;
  58. for(re int i=;i<=n;++i) scanf("%s",a[i]+);
  59. for(re int i=;i<=n;++i)
  60. for(re int j=;j<=m;++j)
  61. mx+=(a[i][j]=='.'),id[i][j]=(i-)*m+j;//mx:人数,建图需要的层数
  62. for(re int i=;i<=n;++i) for(re int j=;j<=m;++j) draw(i,j);
  63. while(bfs()) ;
  64. if(tot) puts("impossible");
  65. else printf("%d",ans);
  66. return ;
  67. }

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. IPC之套接字

    IPC(Inter-Process Communication,进程间通信)实现方式 1)管道: - 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程之间使用(进程的亲缘关系 ...

  2. CentOS7修改为国内yum源

    备份源yum源 如果是国内下载的CentOS很可能国内YUM源已经设置好了. 备份/etc/yum.repos.d/下的*.repo文件. 在CentOS中配置使用网易和阿里的开源镜像 wget ht ...

  3. 22pygame 安装

    实战步骤 pygame 快速体验 飞机大战 实战 确认模块 --pygame pygame 就是一个 Python 模块, 专为电子游戏设计 提示 : 学习第三方模块, 通常最好的参考资料就在官方网站 ...

  4. mysql +keeplive+drbd高可用架构(MHA基于监听端口VIP的高可用)

    1MySQL+DRBD+keepalived高可用架构 DRBD(DistributedReplicatedBlockDevice)是一个基于块设备级别在远程服务器直接同步和镜像数据的开源软件,类似于 ...

  5. Java垃圾回收【GC】机制详解

    一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...

  6. Redux中间件之redux-thunk使用详解

    Redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree .创建store的时 ...

  7. sed \s

    export m1=`free|cut -d ":" -f2|sed -e "s/^\s\s*//g"|head -2|tail -1|cut -d ' ' - ...

  8. Python实例教程

    转自:http://codingdict.com/article/9026 Python 100例-01 题目: 输有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数? Python 1 ...

  9. php array_merge()函数 语法

    php array_merge()函数 语法 作用:把一个或多个数组合并为一个数组.dd马达选型 语法:array_merge(array1,array2,array3...) 参数: 参数 描述 a ...

  10. Android keystore 密码找回

    昨天准备给自己的应用发布一个新版本,在apk打包时,发现之前的用的keystore密码忘了. 蛋碎了一地,我把我所能想到的密码都试了一遍(注:我平常在各个门户网站注册基本上用的都是那几个字母和数字组合 ...