题解

二分答案+Dinic最大流

二分答案\(mid\)

把门拆成\(mid\)个时间点的门

相邻时间的门连一条\(inf\)的边

预处理出每个门到每个人的最短时间

为\(dis[k][i][j]\) 在\((i,j)\)的人到第\(k\)个门最短时间

然后一个人连向每个第\(dis[k][i][j]\)那个时刻的门,容量为\(1\)

然后,源点连向每个人一条容量为\(1\)的边

所有门都连向汇点一条容量为\(1\)的边(其实只要每个最后一个时刻的门连一条容量为\(mid\)的边即可)

Code

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define RG register
  4. using namespace std;
  5. template<class T> inline void read(T &x) {
  6. x = 0; RG char c = getchar(); bool f = 0;
  7. while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
  8. while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
  9. x = f ? -x : x;
  10. return ;
  11. }
  12. template<class T> inline void write(T x) {
  13. if (!x) {putchar(48);return ;}
  14. if (x < 0) x = -x, putchar('-');
  15. int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
  16. for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
  17. }
  18. const int N = 40, inf = 1e9;
  19. int n, m;
  20. int fx[4] = {1, 0, -1, 0};
  21. int fy[4] = {0, 1, 0, -1};
  22. char ch[N][N];
  23. int dis[N<<2][N][N], door, people;
  24. struct BB {
  25. int x, y;
  26. };
  27. queue<BB> Q;
  28. void BFS(int k, int xx, int yy) {
  29. for (int i = 1; i <= n; i++)
  30. for (int j = 1; j <= m; j++)
  31. dis[k][i][j] = inf;
  32. dis[k][xx][yy] = 0; Q.push((BB) {xx, yy});
  33. while (!Q.empty()) {
  34. int x = Q.front().x, y = Q.front().y; Q.pop();
  35. for (int w = 0; w < 4; w++) {
  36. int i = x + fx[w], j = y + fy[w];
  37. if (i < 1 || i > n || j < 1 || j > m || ch[i][j] != '.') continue;
  38. if (dis[k][i][j] > dis[k][x][y]+1)
  39. dis[k][i][j] = dis[k][x][y]+1, Q.push((BB) {i, j});
  40. }
  41. }
  42. }
  43. struct node {
  44. int to, nxt, w;
  45. }g[N*N*N*N];
  46. int last[N*N*N], cur[N*N*N], dep[N*N*N], s, t, gl = 1, p[N][N];
  47. inline void add(int a, int b, int c) {
  48. g[++gl] = (node) {b, last[a], c};
  49. last[a] = gl;
  50. g[++gl] = (node) {a, last[b], 0};
  51. last[b] = gl;
  52. }
  53. queue<int> q;
  54. bool bfs() {
  55. memset(dep, 0, sizeof(dep));
  56. q.push(s); dep[s] = 1;
  57. while (!q.empty()) {
  58. int u = q.front(); q.pop();
  59. for (int i = last[u]; i; i = g[i].nxt) {
  60. int v = g[i].to;
  61. if (!dep[v] && g[i].w) {
  62. dep[v] = dep[u]+1;
  63. q.push(v);
  64. }
  65. }
  66. }
  67. return dep[t] == 0 ? 0 : 1;
  68. }
  69. int dfs(int u, int d) {
  70. if (u == t) return d;
  71. for (int &i = cur[u]; i; i = g[i].nxt) {
  72. int v = g[i].to;
  73. if (g[i].w && dep[v] == dep[u]+1) {
  74. int di = dfs(v, min(d, g[i].w));
  75. if (di) {
  76. g[i].w -= di;
  77. g[i^1].w += di;
  78. return di;
  79. }
  80. }
  81. }
  82. return 0;
  83. }
  84. int Dinic() {
  85. int ans = 0;
  86. while (bfs()) {
  87. for (int i = 1; i <= t; i++)
  88. cur[i] = last[i];
  89. while (int d = dfs(s, inf)) ans += d;
  90. }
  91. return ans;
  92. }
  93. int check(int mid) {
  94. s = door*mid+people+1, t = s+1;
  95. memset(last, 0, sizeof(last)); gl = 1;
  96. for (int k = 1; k <= door; k++)
  97. for (int z = 1; z <= mid; z++) {
  98. if (z < mid)
  99. add((k-1)*mid+z, (k-1)*mid+z+1, inf);
  100. else add(k*mid, t, mid);
  101. }
  102. for (int i = 1; i <= people; i++)
  103. add(s, door*mid+i, 1);
  104. for (int k = 1; k <= door; k++)
  105. for (int i = 1; i <= n; i++)
  106. for (int j = 1; j <= m; j++)
  107. if (ch[i][j] == '.' && dis[k][i][j] <= mid)
  108. add(door*mid+p[i][j], (k-1)*mid+dis[k][i][j], 1);
  109. return Dinic();
  110. }
  111. int main() {
  112. read(n), read(m);
  113. for (int i = 1; i <= n; i++)
  114. scanf("%s", ch[i]+1);
  115. for (int i = 1; i <= n; i++)
  116. for (int j = 1; j <= m; j++)
  117. if (ch[i][j] == 'D')
  118. BFS(++door, i, j);
  119. else if (ch[i][j] == '.') p[i][j] = ++people;
  120. int l = 0, r = people, ans = 666666;
  121. while (l <= r) {
  122. int mid = (l + r) >> 1;
  123. if (check(mid) == people) r = mid-1, ans = mid;
  124. else l = mid+1;
  125. }
  126. if (ans == 666666) puts("impossible");
  127. else printf("%d\n", ans);
  128. return 0;
  129. }

洛谷 P3191 [HNOI2007]紧急疏散EVACUATE(网络最大流)的更多相关文章

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

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

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

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

  3. 洛谷P3376【模板】网络最大流 ISAP

    这篇博客写得非常好呀. 传送门 于是我是DCOI这一届第一个网络流写ISAP的人了,之后不用再被YKK她们嘲笑我用Dinic了!就是这样! 感觉ISAP是会比Dinic快,只分一次层,然后不能增广了再 ...

  4. 洛谷P3376 【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  5. 洛谷 P3376 【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  6. 洛谷——P3376 【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  7. 洛谷 P3376【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  8. 『题解』洛谷P3376 【模板】网络最大流

    Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...

  9. 洛谷 P3376 【模板】网络最大流 题解

    今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值. EK 算法 #include< ...

随机推荐

  1. memcache 加载(对象)所遇到的问题。资源

    <?php $mem =new memcache(); if($mem->connect('127.0.0.1','11211')){ echo '连接OK'.'<br>'; ...

  2. npm link和react native的问题

    问题说明: 需要自己开发一个ReactNative插件,这个插件在独立git仓库,那么怎么把这个插件安装到主项目的依赖里,并且方便对插件的修改调试 方案一: 把插件发布到npm仓库,每次主项目通过np ...

  3. pandas 中的 多条件分割, list 排序

    main_comment_num_3m and avg_group_order_cnt_12m = 0.863230main_comment_score_1m and avg_group_order_ ...

  4. 1.SQL

    Qt和数据库之间的操作非常广泛,Qt支持各种开源和商业的数据库. SQL支持和集成了Qt Model/View结构,让你在GUI编程中更加灵活和方便的使用数据库.

  5. Django框架 之 中间件

    Django框架 之 中间件 浏览目录 中间件介绍 自定义中间件 中间件的执行流程 中间件版登录验证 一.中间件介绍 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个 ...

  6. linux命令下载安装软件

    在ubuntu下获取对应内核源码命令 Ubuntu的包管理系统,为您提供了一种高效快捷的软件管理方式,您只要知道您需要什么软件就可以了,甚至不需要关心它存放在网络上的哪一台服务器中,而且绝大多数的软件 ...

  7. Why does my Authorize Attribute not work?

    the roles of a ClaimsPrincipal are actually just claims create with a type of ClaimsIdentity.RoleCla ...

  8. POJ - 2586 Y2K Accounting Bug (找规律)

    Accounting for Computer Machinists (ACM) has sufferred from the Y2K bug and lost some vital data for ...

  9. Hackfive 使用TextSwitcher和ImageSwitcher实现平滑过渡

    1. 应用场景: 通过向左和向右的导航按钮浏览日期列表 在日期选择空间中改变日期 倒计时始终 新闻刚要 2.用到的知识点是:     TextSwitcher和ImageSwitcher     Te ...

  10. HackSeven Canvas上的动画

    当自定义View的时候,可以利用Canvas给View添加一些动画效果. 下面的例子,是在屏幕上绘制一个红色的小方块,这个小方块会在屏幕上面“乱跳”. 知识点 使用到的知识点: (1) 在View的子 ...