二分答案,网络流判断

将每个门拆点,每个人连向每个门的dis~当前解

然后跑最大流,如果等于人数,即为可行解

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<map>
  7. #define pa pair<int,int>
  8. #define N 405
  9. #define inf 0x7fffffff
  10. using namespace std;
  11. int n,m,p,per=0,door=0,S,T;
  12. pa pos[N];
  13. char s[25],a[25][25];
  14. map<pa,int> pp,dd;
  15. int h,t,xx[N],yy[N];
  16. int dis[N][N];
  17. bool bo[N][N];
  18. int e=2,head[50005];
  19. struct edge{
  20. int u,v,f,next;
  21. }ed[8000005];
  22. void add(int u,int v,int f){
  23. ed[e].u=u; ed[e].v=v; ed[e].f=f;
  24. ed[e].next=head[u]; head[u]=e++;
  25. ed[e].u=v; ed[e].v=u; ed[e].f=0;
  26. ed[e].next=head[v]; head[v]=e++;
  27. }
  28. void bfs(int x,int y){
  29. memset(bo,0,sizeof bo);
  30. h=t=1; xx[1]=x; yy[1]=y;
  31. int now=dd[pa(x,y)];
  32. while(h<=t){
  33. int tx=xx[h],ty=yy[h++];
  34. if(tx-1>0&&a[tx-1][ty]=='.'&&!bo[tx-1][ty]){
  35. dis[pp[pa(tx-1,ty)]][now]=(tx==x&&ty==y?1:dis[pp[pa(tx,ty)]][now]+1);
  36. xx[++t]=tx-1; yy[t]=ty; bo[tx-1][ty]=1;
  37. }
  38. if(tx+1<=n&&a[tx+1][ty]=='.'&&!bo[tx+1][ty]){
  39. dis[pp[pa(tx+1,ty)]][now]=(tx==x&&ty==y?1:dis[pp[pa(tx,ty)]][now]+1);
  40. xx[++t]=tx+1; yy[t]=ty; bo[tx+1][ty]=1;
  41. }
  42. if(ty-1>0&&a[tx][ty-1]=='.'&&!bo[tx][ty-1]){
  43. dis[pp[pa(tx,ty-1)]][now]=(tx==x&&ty==y?1:dis[pp[pa(tx,ty)]][now]+1);
  44. xx[++t]=tx; yy[t]=ty-1; bo[tx][ty-1]=1;
  45. }
  46. if(ty+1<=m&&a[tx][ty+1]=='.'&&!bo[tx][ty+1]){
  47. dis[pp[pa(tx,ty+1)]][now]=(tx==x&&ty==y?1:dis[pp[pa(tx,ty)]][now]+1);
  48. xx[++t]=tx; yy[t]=ty+1; bo[tx][ty+1]=1;
  49. }
  50. }
  51. }
  52. int dep[50005],q[50005];
  53. bool bfs(){
  54. memset(dep,0,sizeof dep);
  55. dep[S]=1; h=t=1; q[1]=S;
  56. while(h<=t){
  57. int x=q[h++];
  58. for(int i=head[x];i;i=ed[i].next){
  59. if(ed[i].f&&!dep[ed[i].v]){
  60. dep[ed[i].v]=dep[x]+1;
  61. q[++t]=ed[i].v;
  62. if(ed[i].v==T) return 1;
  63. }
  64. }
  65. }
  66. return 0;
  67. }
  68. int dfs(int x,int f){
  69. if(x==T||f==0) return f;
  70. int ans=0;
  71. for(int i=head[x];i;i=ed[i].next){
  72. if(ed[i].f&&dep[ed[i].v]==dep[x]+1){
  73. int nxt=dfs(ed[i].v,min(f,ed[i].f));
  74. ed[i].f-=nxt; ed[i^1].f+=nxt;
  75. ans+=nxt; f-=nxt;
  76. if(f==0) break;
  77. }
  78. }
  79. if(ans==0)dep[x]=-1;
  80. return ans;
  81. }
  82. int dinic(){
  83. int ans=0;
  84. while(bfs())
  85. ans+=dfs(S,inf);
  86. return ans;
  87. }
  88. bool work(int x){
  89. e=2; memset(head,0,sizeof head);
  90. S=per+x*door+1;T=S+1;
  91. for(int i=1;i<=per;i++)
  92. for(int j=1;j<=door;j++)
  93. for(int k=dis[i][j]==0?inf:dis[i][j];k<=x;k++)
  94. add(i,per+(k-1)*door+j,1);
  95. for(int i=1;i<=per;i++) add(S,i,1);
  96. for(int i=per+1;i<=per+x*door;i++) add(i,T,1);
  97. if(dinic()==per) return 1;
  98. return 0;
  99. }
  100. int main()
  101. {
  102. scanf("%d%d",&n,&m);
  103. for(int i=1;i<=n;i++){
  104. scanf("%s",s+1);
  105. for(int j=1;j<=m;j++){
  106. a[i][j]=s[j];
  107. pos[++p]=make_pair(i,j);
  108. if(a[i][j]=='.')
  109. pp[pos[p]]=++per;
  110. if(a[i][j]=='D')
  111. dd[pos[p]]=++door;
  112. }
  113. }
  114. for(int i=1;i<=m;i++){
  115. if(a[1][i]=='D')bfs(1,i);
  116. if(a[n][i]=='D')bfs(n,i);
  117. }
  118. for(int i=1;i<=n;i++){
  119. if(a[i][1]=='D')bfs(i,1);
  120. if(a[i][m]=='D')bfs(i,m);
  121. }
  122. for(int i=1;i<=per;i++){
  123. bool booo=1;
  124. for(int j=1;j<=door;j++)
  125. if(dis[i][j]) {booo=0;break;}
  126. if(booo==1){
  127. printf("impossible\n");
  128. return 0;
  129. }
  130. }
  131. int l=1,r=324,mid;
  132. while(l+1<r){
  133. mid=(l+r)/2;
  134. if(work(mid)) r=mid;
  135. else l=mid;
  136. }
  137. if(work(l)) printf("%d\n",l);
  138. else printf("%d\n",r);
  139. return 0;
  140. }

bzoj 1189 紧急疏散 网络流的更多相关文章

  1. BZOJ 1189 紧急疏散(二分+最大流)

    求出所有人撤离的最短时间.由于每扇门只能通过一次,所以不能简单用bfs来搞. 显然答案是有单调性的,考虑二分,问题变成了判断时间x所有人能不能撤离. 考虑最大流.对于每扇门,每个时间通过的人数最多为1 ...

  2. bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流

    [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3626  Solved: 1059[Submit][St ...

  3. BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )

    我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...

  4. BZOJ 1189 【HNOI2007】 紧急疏散evacuate

    题目链接:紧急疏散 这薄脊题我代码不知不觉就写长了…… 这道题二分答案显然,然后用最大流\(check\)即可.设当前二分的答案为\(x\),那么把每扇门拆成\(x\)个点,第\(i\)个代表在第\( ...

  5. BZOJ 1189 [HNOI2007]紧急疏散evacuate

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

  6. 【BZOJ 1189】[HNOI2007]紧急疏散evacuate

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

  7. AC日记——[HNOI2007]紧急疏散evacuate bzoj 1189

    [HNOI2007]紧急疏散evacuate 思路: 处理每个人到门的最短路: 然后二分答案: s向人连边流量1: 人向门拆分后的点连边流量1(拆成400,前一个点连当前点流量INF): 然后门向t连 ...

  8. bzoj 1189: [HNOI2007]紧急疏散evacuate 分层图最大流_拆点_二分

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

  9. BZOJ 1189 二分匹配 || 最大流

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

随机推荐

  1. 简单了解JS中的几种遍历

    忙了好一段时间,项目上线后终于有那么一点点空档期静下来整理一些问题了.当我们在开发项目的时候,用到遍历的地方肯定少不了,那么我们有那么多的遍历方法,在不同情况下用那种方法会更优雅而且还没bug呢? 首 ...

  2. 《深入理解java虚拟机》读书笔记1--java内存区域

    Java内存管理 本文主要介绍Java虚拟机运行时的内存区域是如何划分的.Java对象的创建过程.Java对象的内存布局.Java对象的访问定位 一:运行时区域划分 主要可以分为以下 几个: 程序计数 ...

  3. Webapck项目开发基本构建及配置

    1.创建项目文件夹 myapp 手动创建myapp,或mkdir myapp 2.cd myapp 3.npm init (初始化项目) 4.一路回车(关于项目信息的填写,可以不写,一路回车即可) 可 ...

  4. % 与 format 进行字符串格式化

    字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 1.百分号方式 %[(name)][flags][width].[precision]typecode (name) ...

  5. 如何实现Zabbix的主动注册功能

    主动注册(Active Agent Auto-Registration),顾名思义,无需在Zabbix Web上手动添加host信息,即可实现主机的监控. 它是由Agent主动向Server注册. 相 ...

  6. Aptana下Django1.6以后的项目模板结构改造

    Django1.6以后的manage.py放在项目包目录的根目录下,这种情况下在create app的app也在这个目录下面,由此可能导致app的名称有可能会和广大的内建包或者第三方包发生命名冲突,解 ...

  7. js中window对象的opener属性的一个坑

    2018-05-08 17:48:33 今天我编写代码碰到了一个让我纠结了很久的坑,特别想在此说一下,让其他人避免我踏过的这个坑. 这个坑就是:在我自己写的子窗口中用opener属性却获取不到父窗口的 ...

  8. python笔记:#001#python简介

    认识 Python 人生苦短,我用 Python -- Life is short, you need Python 目标 Python 的起源 为什么要用 Python? Python 的特点 Py ...

  9. oozie: GC overhead limit exceeded 解决方法

    1.异常表现形式 1)  提示信息      Error java.lang.OutOfMemoryError: GC overhead limit exceeded 2)提示出错      Erro ...

  10. Effective C++ 读书笔记(39-45)

    条款三十九:明智而审慎的使用private继承 1.C++裁定凡是独立(非附属)对象都必须有非零大小. class Empty{};//没有数据,所以其对象应该不使用任何内存 class HoldAn ...