*题目描述:
发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是’.’,那么表示这是一块空地;如果是’X’,那么表示这是一面墙,如果是’D’,那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。

*输入:
输入文件第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,以下N行M列描述一个N M的矩阵。其中的元素可为字符’.’、’X’和’D’,且字符间无空格。

*输出:
只有一个整数K,表示让所有人安全撤离的最短时间,如果不可能撤离,那么输出’impossible’(不包括引号)。

*样例输入:
5 5
XXXXX
X…D
XX.XX
X..XX
XXDXX

*样例输出:
3

*题解:
bfs+枚举答案网络流判定。
先把每个点到每个门的最短距离用bfs求出来,然后建分层图来跑网络流,直到最大流为点数时就是答案。

*代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <queue>
  6. #ifdef WIN32
  7. #define LL "%I64d"
  8. #else
  9. #define LL "%lld"
  10. #endif
  11. #ifdef CT
  12. #define debug(...) printf(__VA_ARGS__)
  13. #define setfile()
  14. #else
  15. #define debug(...)
  16. #define filename ""
  17. #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
  18. #endif
  19. #define R register
  20. #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
  21. #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
  22. #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
  23. #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
  24. #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
  25. #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
  26. char B[1 << 15], *S = B, *T = B;
  27. inline int F()
  28. {
  29. R char ch; R int cnt = 0; R bool minus = 0;
  30. while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
  31. ch == '-' ? minus = 1 : cnt = ch - '0';
  32. while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
  33. return minus ? -cnt : cnt;
  34. }
  35. #define maxn 30
  36. #define P std::pair<int, int>
  37. #define mkp std::make_pair
  38. #define fir first
  39. #define sec second
  40. char str[maxn][maxn];
  41. int id[maxn][maxn], dis[maxn * maxn][maxn * maxn], n, m;
  42. const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
  43. P door[maxn * maxn], p[maxn * maxn];
  44. struct Queue
  45. {
  46. int x, y, step;
  47. }q2[maxn * maxn * 10];
  48. bool vis[maxn][maxn];
  49. inline void bfs(R int x, R int y, R int now)
  50. {
  51. memset(vis, 0, sizeof (vis));
  52. memset(dis[now], 63, sizeof (dis[now]));
  53. R int head = 0, tail = 1;
  54. q2[1] = (Queue) {x, y, 0};
  55. R bool flag = 1;
  56. while (head < tail)
  57. {
  58. ++head;
  59. for (R int i = 0; i < 4; ++i)
  60. {
  61. R int nx = q2[head].x + dx[i], ny = q2[head].y + dy[i];
  62. if (nx && ny && nx <= n && ny <= m && !vis[nx][ny])
  63. {
  64. vis[nx][ny] = 1;
  65. if (str[nx][ny] == 'D') dis[now][id[nx][ny]] = q2[head].step + 1, flag = 0;
  66. else if (str[nx][ny] == '.')
  67. {
  68. q2[++tail] = (Queue) {nx, ny, q2[head].step + 1};
  69. }
  70. }
  71. }
  72. }
  73. if (flag) {puts("impossible");exit(0);}
  74. }
  75. #define maxp 10010
  76. #define maxm 1000010
  77. struct Edge
  78. {
  79. Edge *next, *rev;
  80. int to, cap;
  81. }*last[maxp], *cur[maxp], e[maxm], *ecnt = e;
  82. int dep[maxp], s, t, ans;
  83. std::queue<int> q;
  84. inline void link(R int a, R int b, R int w)
  85. {
  86. *++ecnt = (Edge) {last[a], ecnt + 1, b, w}; last[a] = ecnt;
  87. *++ecnt = (Edge) {last[b], ecnt - 1, a, 0}; last[b] = ecnt;
  88. }
  89. inline bool bfs()
  90. {
  91. memset(dep, -1, sizeof (dep));
  92. q.push(t); dep[t] = 0;
  93. while (!q.empty())
  94. {
  95. R int now = q.front(); q.pop();
  96. for (R Edge *iter = last[now]; iter; iter = iter -> next)
  97. {
  98. R int pre = iter -> to;
  99. if (iter -> rev -> cap && dep[pre] == -1)
  100. {
  101. dep[pre] = dep[now] + 1;
  102. q.push(pre);
  103. }
  104. }
  105. }
  106. return dep[s] != -1;
  107. }
  108. int dfs(R int x, R int f)
  109. {
  110. if (x == t) return f;
  111. R int used = 0;
  112. for (R Edge* &iter = cur[x]; iter; iter = iter -> next)
  113. {
  114. R int pre = iter -> to;
  115. if (iter -> cap && dep[x] == dep[pre] + 1)
  116. {
  117. R int v = dfs(pre, dmin(iter -> cap, f - used));
  118. iter -> cap -= v;
  119. iter -> rev -> cap += v;
  120. used += v;
  121. if (used == f) return f;
  122. }
  123. }
  124. if (!used) dep[x] = -1;
  125. return used;
  126. }
  127. inline void dinic()
  128. {
  129. while (bfs())
  130. {
  131. memcpy(cur, last, sizeof last);
  132. ans += dfs(s, 0x7fffffff);
  133. }
  134. }
  135. int main()
  136. {
  137. // setfile();
  138. scanf("%d%d", &n, &m);
  139. R int pcnt = 0, dcnt = 0;
  140. for (R int i = 1; i <= n; ++i)
  141. scanf("%s", str[i] + 1);
  142. for (R int i = 1; i <= n; ++i)
  143. for (R int j = 1; j <= m; ++j)
  144. if (str[i][j] == 'D')
  145. door[++dcnt] = mkp(i, j), id[i][j] = dcnt;
  146. else if (str[i][j] == '.') p[++pcnt] = mkp(i, j);
  147. for (R int i = 1; i <= pcnt; ++i)
  148. bfs(p[i].fir, p[i].sec, i);
  149. R int cnt = pcnt;
  150. s = 0; t = maxp - 2;
  151. for (R int i = 1; i <= pcnt; ++i) link(s, i, 1);
  152. for (R int k = 1; ; ++k)
  153. {
  154. for (R int i = 1; i <= dcnt; ++i)
  155. {
  156. ++cnt;
  157. link(cnt, t, 1);
  158. for (R int j = 1; j <= pcnt; ++j)
  159. if (dis[j][i] <= k)
  160. link(j, cnt, 1);
  161. }
  162. dinic();
  163. if (ans == pcnt) return !printf("%d\n", k );
  164. }
  165. return 0;
  166. }
  167. /*
  168. 5 5
  169. XXXXX
  170. X...D
  171. XX.XX
  172. X..XX
  173. XXDXX
  174. */

【bzoj1189】[HNOI2007]紧急疏散evacuate的更多相关文章

  1. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

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

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

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

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

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

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

  5. BZOJ1189 [HNOI2007]紧急疏散evacuate 【二分 + 网络流】

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

  6. BZOJ1189: [HNOI2007]紧急疏散evacuate(二分答案,最大流)

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

  7. 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate

    [法一]枚举Time(0~N*M): S->'.'(1); 'D'->T(Time); '.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意di ...

  8. 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流

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

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

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

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

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

随机推荐

  1. javascript number与isNan

    number 与 isnan Number:表示整数和浮点数 NaN:即非数值(not a Number)是 一个特殊的数值.是Number类型的一种. 说明:1.任何涉及NaN的操作(例如Nan/1 ...

  2. 第八周课程总结&实验报告

    实验六 Java异常 •实验目的 •理解异常的基本概念: •掌握异常处理方法及熟悉常见异常的捕获方法. • 实验要求 •练习捕获异常.声明异常.抛出异常的方法.熟悉try和catch子句的使用. •掌 ...

  3. 零基础学习前端1-1配置node及npm环境变量

    零基础学习前端1-1配置node及npm环境变量 ## 1-1配置node及npm环境变量 首先:下载node 可以直接去官方网站下载 1.首先从官网下载安装包 https://nodejs.org/ ...

  4. 常用邮件SMTP POP3服务器地址大全

    #阿里云邮箱(mail.aliyun.com): POP3服务器地址:pop3.aliyun.com(SSL加密端口:995:非加密端口:110) SMTP服务器地址:smtp.aliyun.com( ...

  5. npm学习(二)之如何防止权限错误

    如何防止权限错误 如果您在尝试全局安装包时看到EACCES错误,请阅读本章.如果更改安装npm的目录,通常可以避免此错误.要做到这一点,要么使用版本管理器重新安装npm(推荐)或手动更改npm的默认目 ...

  6. echats 油表盘 鼠标拖动指针改变数值

    近期需要做一个鼠标拖动完成油表盘数值改变的功能,使用canvas感觉太麻烦,而且指针不太好监听和拖动,只能另谋出路,在网上参考了某位大神的操作,最终选择了echats来解决这个问题.废话不多说,直接上 ...

  7. qt使用QWT注意事项

    当继承某个QWT类时,有是使用O_OBJECT弘会出现问题 切记在工程文件里别忘了添加这一句 DEFINES+=QWT_DLL

  8. PHP trait与单例模式 (一次编写,到处使用)

    一  trait php是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性. 个人理解的trait是: trait = abstract class - ...

  9. React结合AntD的upload组件写头像上传

    upload组件里面action就是调upload接口,获取图片url地址 setImg获取url,点击保存传到后台   action 上传头像方法 //上传头像 changeImg = info = ...

  10. 解决echarts内存泄露的问题

    clear方法和dispose方法 一种是调用clear方法,一种是dispose方法.第一种是清理echarts 但是不销毁实例.第二种是销毁实例,再次使用需要重新构建实例 1. var chart ...