【bzoj1189】[HNOI2007]紧急疏散evacuate
来源:互联网 发布:经济型酒店数据分析 编辑:程序博客网 时间:2024/03/29 14:37
*题目描述:
发生了火警,所有人员需要紧急疏散!假设每个房间是一个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求出来,然后建分层图来跑网络流,直到最大流为点数时就是答案。
*代码:
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#ifdef WIN32 #define LL "%I64d"#else #define LL "%lld"#endif#ifdef CT #define debug(...) printf(__VA_ARGS__) #define setfile() #else #define debug(...) #define filename "" #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)#endif#define R register#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)#define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))char B[1 << 15], *S = B, *T = B;inline int F(){ R char ch; R int cnt = 0; R bool minus = 0; while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ; ch == '-' ? minus = 1 : cnt = ch - '0'; while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0'; return minus ? -cnt : cnt;}#define maxn 30#define P std::pair<int, int>#define mkp std::make_pair#define fir first#define sec secondchar str[maxn][maxn];int id[maxn][maxn], dis[maxn * maxn][maxn * maxn], n, m;const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};P door[maxn * maxn], p[maxn * maxn];struct Queue{ int x, y, step;}q2[maxn * maxn * 10];bool vis[maxn][maxn];inline void bfs(R int x, R int y, R int now){ memset(vis, 0, sizeof (vis)); memset(dis[now], 63, sizeof (dis[now])); R int head = 0, tail = 1; q2[1] = (Queue) {x, y, 0}; R bool flag = 1; while (head < tail) { ++head; for (R int i = 0; i < 4; ++i) { R int nx = q2[head].x + dx[i], ny = q2[head].y + dy[i]; if (nx && ny && nx <= n && ny <= m && !vis[nx][ny]) { vis[nx][ny] = 1; if (str[nx][ny] == 'D') dis[now][id[nx][ny]] = q2[head].step + 1, flag = 0; else if (str[nx][ny] == '.') { q2[++tail] = (Queue) {nx, ny, q2[head].step + 1}; } } } } if (flag) {puts("impossible");exit(0);}}#define maxp 10010#define maxm 1000010struct Edge{ Edge *next, *rev; int to, cap;}*last[maxp], *cur[maxp], e[maxm], *ecnt = e;int dep[maxp], s, t, ans;std::queue<int> q;inline void link(R int a, R int b, R int w){ *++ecnt = (Edge) {last[a], ecnt + 1, b, w}; last[a] = ecnt; *++ecnt = (Edge) {last[b], ecnt - 1, a, 0}; last[b] = ecnt;}inline bool bfs(){ memset(dep, -1, sizeof (dep)); q.push(t); dep[t] = 0; while (!q.empty()) { R int now = q.front(); q.pop(); for (R Edge *iter = last[now]; iter; iter = iter -> next) { R int pre = iter -> to; if (iter -> rev -> cap && dep[pre] == -1) { dep[pre] = dep[now] + 1; q.push(pre); } } } return dep[s] != -1;}int dfs(R int x, R int f){ if (x == t) return f; R int used = 0; for (R Edge* &iter = cur[x]; iter; iter = iter -> next) { R int pre = iter -> to; if (iter -> cap && dep[x] == dep[pre] + 1) { R int v = dfs(pre, dmin(iter -> cap, f - used)); iter -> cap -= v; iter -> rev -> cap += v; used += v; if (used == f) return f; } } if (!used) dep[x] = -1; return used;}inline void dinic(){ while (bfs()) { memcpy(cur, last, sizeof last); ans += dfs(s, 0x7fffffff); }}int main(){// setfile(); scanf("%d%d", &n, &m); R int pcnt = 0, dcnt = 0; for (R int i = 1; i <= n; ++i) scanf("%s", str[i] + 1); for (R int i = 1; i <= n; ++i) for (R int j = 1; j <= m; ++j) if (str[i][j] == 'D') door[++dcnt] = mkp(i, j), id[i][j] = dcnt; else if (str[i][j] == '.') p[++pcnt] = mkp(i, j); for (R int i = 1; i <= pcnt; ++i) bfs(p[i].fir, p[i].sec, i); R int cnt = pcnt; s = 0; t = maxp - 2; for (R int i = 1; i <= pcnt; ++i) link(s, i, 1); for (R int k = 1; ; ++k) { for (R int i = 1; i <= dcnt; ++i) { ++cnt; link(cnt, t, 1); for (R int j = 1; j <= pcnt; ++j) if (dis[j][i] <= k) link(j, cnt, 1); } dinic(); if (ans == pcnt) return !printf("%d\n", k ); } return 0;}/*5 5XXXXXX...DXX.XXX..XXXXDXX*/
0 0
- bzoj1189 [HNOI2007]紧急疏散evacuate
- bzoj1189: [HNOI2007]紧急疏散evacuate
- BZOJ1189 [HNOI2007]紧急疏散evacuate
- 【bzoj1189】[HNOI2007]紧急疏散evacuate
- bzoj1189: [HNOI2007]紧急疏散evacuate
- BZOJ1189: [HNOI2007]紧急疏散evacuate
- 【bzoj1189】[HNOI2007]紧急疏散evacuate 二分+dinic
- [bzoj1189][HNOI2007]紧急疏散
- 【HNOI2007】bzoj1189 紧急疏散
- 【BZOJ1189】【HNOI2007】紧急疏散evacuate 二分答案+最大流check
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate【最大流】【二分】
- [BZOJ1189][HNOI2007]紧急疏散evacuate(bfs+二分+最大流)
- [BZOJ1189][HNOI2007]紧急疏散evacuate(二分+网络流)
- 最大流——BZOJ1189/Luogu3191 [HNOI2007]紧急疏散evacuate
- bzoj1189: [HNOI2007]紧急疏散evacuate(二分+最大流+宽搜)
- BZOJ1189【HNOI2007】紧急疏散evacuate <二分答案+网络流>
- bzoj1189 [HNOI2007]紧急疏散EVACUATE spfa+网络流+二分
- 1189: [HNOI2007]紧急疏散evacuate
- NHibernate之配置文件属性说明
- 使用sparksql开发pv,uv,二跳率
- 切图分辨率
- javascript去掉数组中的重复项
- 使用js实现图片裁剪
- 【bzoj1189】[HNOI2007]紧急疏散evacuate
- android 中线程的启动与休眠
- [jQuery]$.ajax()方法详解及实例
- iOS开发 适配iOS10
- Java实现从一个数字中删除给定个数的数得到一个最大整数
- sparksession
- JAVASCRIPT赋值时使用||和&&
- 不登录CSDN就获取需要登陆的JSON数据 (已解决)
- 数据与统计