传送门

这一题很容易想到网络流

一开始傻逼地模拟整个图每一个时间的情况,显然会爆炸

发现我们只要考虑起点到门之间的距离,不用每一步只走一格

所以直接 $BFS$ 预处理距离然后二分答案,网络流判断即可

注意到了门就不能走了,所以门不能连边出去

总的来说挺傻逼的一题...但是我就是没想到...

某位不愿意透露姓名的神仙还有一种牛逼的费用流做法,代码极短$STO$

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. typedef long long ll;
  9. inline int read()
  10. {
  11. int x=,f=; char ch=getchar();
  12. while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
  13. while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
  14. return x*f;
  15. }
  16. const int N=2e5+,M=5e6+,INF=1e9+,xx[]={,,,-},yy[]={,,-,};
  17. int fir[N],from[M<<],to[M<<],val[M<<],cntt=;
  18. inline void add(int a,int b,int c)
  19. {
  20. from[++cntt]=fir[a]; fir[a]=cntt;
  21. to[cntt]=b; val[cntt]=c;
  22. from[++cntt]=fir[b]; fir[b]=cntt;
  23. to[cntt]=a; val[cntt]=;
  24. }
  25. int n,m,tot,id[][][],sum;
  26. int dep[N],S,T;
  27. queue <int> Q;
  28. bool BFS()
  29. {
  30. for(int i=;i<=tot;i++) dep[i]=;
  31. Q.push(S); dep[S]=;
  32. while(!Q.empty())
  33. {
  34. int x=Q.front(); Q.pop();
  35. for(int i=fir[x];i;i=from[i])
  36. {
  37. int &v=to[i]; if(dep[v]||(!val[i])) continue;
  38. dep[v]=dep[x]+; Q.push(v);
  39. }
  40. }
  41. return dep[T]>;
  42. }
  43. int DFS(int x,int mxfl)
  44. {
  45. if(x==T||!mxfl) return mxfl;
  46. int fl=,res;
  47. for(int i=fir[x];i;i=from[i])
  48. {
  49. int &v=to[i]; if(dep[v]!=dep[x]+||!val[i]) continue;
  50. if( res=DFS(v,min(mxfl,val[i])) )
  51. {
  52. mxfl-=res; fl+=res;
  53. val[i]-=res; val[i^]+=res;
  54. if(!mxfl) break;
  55. }
  56. }
  57. return fl;
  58. }
  59. char mp[][];
  60. int dis[][][][];
  61. struct dat{
  62. int x,y;
  63. dat (int a=,int b=) { x=a,y=b; }
  64. };
  65. queue <dat> q;
  66. void pre()
  67. {
  68. memset(dis,0x3f,sizeof(dis));
  69. for(int i=;i<=n;i++)
  70. for(int j=;j<=m;j++)
  71. {
  72. if(mp[i][j]!='.') continue;
  73. q.push(dat(i,j)); dis[i][j][i][j]=;
  74. while(!q.empty())
  75. {
  76. dat u=q.front(); q.pop();
  77. for(int k=;k<;k++)
  78. {
  79. int tx=u.x+xx[k],ty=u.y+yy[k];
  80. if(tx<||tx>n||ty<||ty>m||mp[tx][ty]=='X'||dis[i][j][tx][ty]<M) continue;
  81. dis[i][j][tx][ty]=dis[i][j][u.x][u.y]+;
  82. if(mp[tx][ty]!='D') q.push(dat(tx,ty));
  83. }
  84. }
  85. }
  86. }
  87. bool check(int mid)
  88. {
  89. for(int i=;i<=tot;i++) fir[i]=; tot=; S=,T=; cntt=;
  90. for(int i=;i<=n;i++)
  91. for(int j=;j<=m;j++)
  92. if(mp[i][j]=='.') id[][i][j]=++tot,add(S,tot,);
  93. for(int t=;t<=mid;t++)
  94. for(int k=;k<=n;k++)
  95. for(int l=;l<=m;l++)
  96. if(mp[k][l]=='D') id[t][k][l]=++tot,add(tot,T,);
  97. for(int i=;i<=n;i++)
  98. for(int j=;j<=m;j++)
  99. {
  100. if(mp[i][j]!='.') continue;
  101. for(int t=;t<=mid;t++)
  102. for(int k=;k<=n;k++)
  103. for(int l=;l<=m;l++)
  104. if(mp[k][l]=='D'&&dis[i][j][k][l]<=t) add(id[][i][j],id[t][k][l],INF);
  105. }
  106. int now=;
  107. while(BFS())
  108. {
  109. now+=DFS(S,INF);
  110. if(now>=sum) break;
  111. }
  112. for(int t=;t<=mid;t++)
  113. for(int i=;i<=n;i++)
  114. for(int j=;j<=m;j++) id[t][i][j]=;
  115. return now>=sum;
  116. }
  117. int main()
  118. {
  119. n=read(),m=read();
  120. for(int i=;i<=n;i++) scanf("%s",mp[i]+);
  121. for(int i=;i<=n;i++)
  122. for(int j=;j<=m;j++) sum+=(mp[i][j]=='.');
  123. pre();
  124. int L=,R=n*m,mid,ans=M;
  125. while(L<=R)
  126. {
  127. mid=L+R>>;
  128. if(check(mid)) R=mid-,ans=mid;
  129. else L=mid+;
  130. }
  131. if(ans==M) printf("impossible\n");
  132. else printf("%d\n",ans);
  133. return ;
  134. }

P3191 [HNOI2007]紧急疏散EVACUATE的更多相关文章

  1. P3191 [HNOI2007]紧急疏散EVACUATE(费用流)

    P3191 [HNOI2007]紧急疏散EVACUATE 费用流+卡常优化 我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护 于是根据时间分层,到门的时候再计算代价,即代价$=$层数 每经 ...

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

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

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

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

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

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

  5. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

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

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

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

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

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

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

  9. bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate

    http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...

随机推荐

  1. JSP上传一个文件夹

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id=" ...

  2. HDU 6614 AND Minimum Spanning

    Time limit 1000 ms Memory limit 131072 kB OS Windows 中文题意 给一张n个点的无向完全图(输入一个n就完事了),每个点标号为1~n,每条边的边权为它 ...

  3. clientX、pageX、offsetX、screenX的区别

    这几个属性的区别说难不难,可是很容易搞混,很长一段时间没用,发现又忘记区别了,记不清哪个是哪个!真的很抓狂! 区别: clientX.clientY: 相对于浏览器窗口可视区域的X,Y坐标(窗口坐标) ...

  4. (24)Python实现递归生成或者删除一个文件目录及文件

    def removeDir(dirPath): ''' Created by Wu Yongcong 2017-8-18 :param dirPath: :return: ''' if not os. ...

  5. oracle触发器update本表数据

    功能: 1. 允许/限制对表的修改 2. 自动生成派生列,比如自增字段 3. 强制数据一致性 4. 提供审计和日志记录 5. 防止无效的事务处理 6. 启用复杂的业务逻辑 开始 create trig ...

  6. docker学习与应用

    概要 众所周知,Docker是当前非常火的虚拟化容器技术,对于它的优势以及使用场景网上的资料非常多,这里我推荐大家去这个网站去详细学习docker. 我这里就写一下作为一名后端开发程序员,自己学习do ...

  7. PCIE手札

    PCIE兼容了大部分PCI总线的特性,区别在于使用串行差分总线代替了并行总线,并实现了协议分层.PCIE的带宽与LANE数量和时钟频率相关,时钟频率支持2.5G和5G,Lane支持x1/x2/x4/x ...

  8. 三十六、python 中subprocess介绍

    import subprocess 1.执行系统命令subprocess.call('ipconfig') #shell=False时,拼接命令分开写,放在列表中,等于True时,可写一块,空格隔开例 ...

  9. format和urlencode的使用对比

    一:format的基本语法使用 基本语法是通过 {} 和 : 来代替以前的 % . format 函数可以接受不限个参数,位置可以不按顺序. 例如: >>>"{} {}&q ...

  10. Vue知识整理6:JavaScript表达式

    可在vue中运用js表达式,完成数据的运算(包括三元运算).比较等操作.