[HNOI2007]紧急疏散
二分+网络流判定
首先处理出每个人和门间的距离
二分时间,连边时把每个门拆成mid个,一个人能在mid时间内到达,他也可以在这等一会儿,那么这mid个门之间连边
如果可以在x的时间内到达,那么x~mid之间他都可以出去,所以门向门加一连边
奉上未AC代码千万别复制
# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
# define Copy(a, b) memcpy(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(1010), __(1e6 + 10), INF(2147483647);
IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
int n, m, mp[30][30], cntr, cntd, dis[_][_], id[_][_];
int tcnt, tmp1[_ * 100], tmp2[__], w[__], fst[_ * 100], nxt[__], to[__], cnt, S, T, lev[_ * 100], cur[_ * 100], max_flow;
queue <int> Q;
IL void Add(RG int u, RG int v, RG int f){
w[cnt] = f; to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++;
w[cnt] = 0; to[cnt] = u; nxt[cnt] = fst[v]; fst[v] = cnt++;
}
IL int Dfs(RG int u, RG int maxf){
if(u == T) return maxf;
RG int ret = 0;
for(RG int &e = cur[u]; e != -1; e = nxt[e]){
if(lev[to[e]] != lev[u] + 1 || !w[e]) continue;
RG int f = Dfs(to[e], min(w[e], maxf - ret));
ret += f; w[e ^ 1] += f; w[e] -= f;
if(ret == maxf) break;
}
return ret;
}
IL bool Bfs(){
Fill(lev, 0); lev[S] = 1; Q.push(S);
while(!Q.empty()){
RG int u = Q.front(); Q.pop();
for(RG int e = fst[u]; e != -1; e = nxt[e]){
if(lev[to[e]] || !w[e]) continue;
lev[to[e]] = lev[u] + 1;
Q.push(to[e]);
}
}
return lev[T];
}
IL int Maxflow(){ for(max_flow = 0; Bfs(); ) Copy(cur, fst), max_flow += Dfs(S, INF); return max_flow; }
struct Data{ int x, y, d; } u;
queue <Data> que;
int dx[] = {1, -1}, dy[] = {0, 0, 1, -1}, vis[_][_];
IL void BFS(RG int x, RG int y, RG int ID){
Fill(vis, 0); que.push((Data){x, y}); vis[x][y] = 1;
while(!que.empty()){
u = que.front(); que.pop();
for(RG int i = 0; i < 4; ++i){
RG int xx = u.x + dx[i], yy = u.y + dy[i];
if(xx < 1 || yy < 1 || xx > n || yy > m || mp[xx][yy] == 1 || vis[xx][yy]) continue;
vis[xx][yy] = 1;
if(mp[xx][yy] == 2) dis[ID][id[xx][yy]] = u.d + 1;
que.push((Data){xx, yy, u.d + 1});
}
}
}
IL int Check(RG int x){
Fill(fst, -1); cnt = 0; T = cntr + cntd * x + 1;
for(RG int i = 1; i <= cntr; ++i) Add(S, i, 1);
for(RG int i = 1; i <= cntd; ++i)
for(RG int j = 1; j <= x; ++j){
Add(cntr + x * (i - 1) + j, T, 1);
if(j < x) Add(cntr + x * (i - 1) + j, cntr + x * (i - 1) + j + 1, INF);
}
for(RG int i = 1; i <= cntr; ++i)
for(RG int j = 1; j <= cntd; ++j)
if(dis[i][j] && dis[i][j] <= x) Add(i, cntr + x * (j - 1) + dis[i][j], INF);
return Maxflow();
}
int main(RG int argc, RG char* argv[]){
n = Read(); m = Read();
for(RG int i = 1; i <= n; ++i){
RG char c[30]; scanf(" %s", c);
for(RG int j = 1; j <= m; ++j){
if(c[j - 1] == '.') id[i][j] = ++cntr;
else if(c[j - 1] == 'D') mp[i][j] = 2, id[i][j] = ++cntd;
else mp[i][j] = 1;
}
}
for(RG int i = 1; i <= n; ++i)
for(RG int j = 1; j <= m; ++j)
if(!mp[i][j]) BFS(i, j, id[i][j]);
RG int l = 0, r = 400, ans = -1;
while(l <= r){
RG int mid = (l + r) >> 1;
if(Check(mid) == cntr) r = mid - 1, ans = mid;
else l = mid + 1;
}
ans == -1 ? puts("impossible") : printf("%d\n", ans);
return 0;
}
[HNOI2007]紧急疏散的更多相关文章
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1132 Solved: 412[Submi ...
- BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )
我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...
- [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate
http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...
- bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流
[HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3626 Solved: 1059[Submit][St ...
- 【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- 【BZOJ1189】[HNOI2007]紧急疏散evacuate 动态加边网络流
[BZOJ1189][HNOI2007]紧急疏散evacuate Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空 ...
- AC日记——[HNOI2007]紧急疏散evacuate bzoj 1189
[HNOI2007]紧急疏散evacuate 思路: 处理每个人到门的最短路: 然后二分答案: s向人连边流量1: 人向门拆分后的点连边流量1(拆成400,前一个点连当前点流量INF): 然后门向t连 ...
- P3191 [HNOI2007]紧急疏散EVACUATE(费用流)
P3191 [HNOI2007]紧急疏散EVACUATE 费用流+卡常优化 我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护 于是根据时间分层,到门的时候再计算代价,即代价$=$层数 每经 ...
随机推荐
- laravel5.4+vue+vux+element的环境搭配
最近因为项目的需要,需要搭配一个这样的环境.之前做过的东西没有这样用过,在网上找了半天不是过于简单就是根本行不通,自己踩了半天的坑,终于搭配成功. 首先下载laravel5.4,直接去官网一键安装包或 ...
- 当inline元素包裹block元素时会发生什么
经常有图片链接写法如下: <a href="www.baidu.com"><img src="baidu.jpg" /></a&g ...
- 基于Docker构建带有Rsync的Jenkins
1.编辑Dockerfile文件 FROM jenkins USER root ADD sources.list /etc/apt/sources.list RUN apt-get update &a ...
- zabbix邮件报警设置
第一.安装邮件发送工具mailx 这里我选择的是mailx,所以的关闭其他的邮件发送工具 service sendmailstop #关闭 chkconfig sendmailoff #禁止开机启 ...
- css为第几个倍数元素添加样式
//3n就是3的倍数都加这个样式*/.list li:nth-child(3n){ border-bottom:1px;}
- FFmepg 如何在 window 上使用?
下载FFmepg官网库直接使用即可. avdevice.lib avcodec.lib avfilter.lib avformat.lib avutil.lib postproc.lib swresa ...
- UVALive - 4329 Ping pong 树状数组
这题不是一眼题,值得做. 思路: 假设第个选手作为裁判,定义表示在裁判左边的中的能力值小于他的人数,表示裁判右边的中的能力值小于他的人数,那么可以组织场比赛. 那么现在考虑如何求得和数组.根据的定义知 ...
- CodeForces-749A
要求组成n的素数最多,根据n的奇偶讨论:如果n是偶数,直接打印n/2个数字'2'就可以了:如果n是基数,则先打印一个'3',再打印(n-3)/2个数字'2'就可以了. AC代码: #include&l ...
- java网络编程(6)——实现一个服务器把小写转大写
实现一个服务器,通过我们发送的文本数据,然后转回大写放回,实现一个服务端与客户端的交互,用over来作为结束标记,具体代码如下: 客户端: package com.seven.tcp; import ...
- 自动化测试 selenium中WebDriver 和WebElement的区别
之前在做UI自动化测试中 经常会用到 WebDriver 和 WebElement两个类 以前对这两个类总感觉有点傻傻分不清 昨天看了下之前下的代码 结合自己的理解 对着两个类的区别和关系 ...