[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 费用流+卡常优化 我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护 于是根据时间分层,到门的时候再计算代价,即代价$=$层数 每经 ...
随机推荐
- 【linux之设备,分区,文件系统】
一.设备 IDE磁盘的设备文件采用/dev/hdx来命名,分区则采用/dev/hdxy来命名,其中x表示磁盘(a是第一块磁盘,b是第二块磁盘,以此类推), y代表分区的号码(由1开始,..3以此类推) ...
- iOS "此证书由未知颁发机构签名"此问题的解决方法
前段时间制作证书时把以前钥匙串中的证书全删除了,然后在制作新证书的时候就出现了"此证书由未知颁发机构签名"的红色警告,通过查找资料发现出现此问题的原因是:我把钥匙串中的此证书给删除 ...
- ss-redir 的 iptables 配置(透明代理)
透明代理指对客户端透明,客户端不需要进行任何设置就使用了网管设置的代理规则 创建 /etc/ss-redir.json 本地监听 7777 运行ss-redir -v -c /etc/ss-redir ...
- ubuntu17.10 安装firefox的flash
1. flash下载地址:https://get.adobe.com/flashplayer/ 2. 选择tar.gz for linux 3. 下载后解压tar包.里面有个libflashplaye ...
- VB 如何调用 c++ DLL?
``` ```Class MainWindow 'ByVal 值传递 ByRef 引用传递 'Function 有返回值 Sub 无返回值 'C语言数据类型在VisualBasic中声明为调用时使用的 ...
- css y轴溢出滚动条,x轴溢出显示
这个是我工作中遇到的一个问题,困扰了我好几天,彻底理解了什么叫思路很重要. 黄色盒子里的内容是要超出出现滚动条的,红色的方块是根据另外的元素去定位的,于是呢 我就加上了 overflow-y:auto ...
- MySQL 5.7 多主一丛同步的数据库配置(将多处数据源合并到一点)
工作需要,笔记之用.文章很长,倒一杯茶慢慢看. 数据库的应用场景颇多,如 数据库双机同步,一主多从,多主多从,多主一从等:下文记录多主一从的配置及测试. 大多数复制场景中是一主或者一主多从.这种拓扑用 ...
- ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)
上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...
- 3.2 PCI设备的数据传递
PCI设备的数据传递使用地址译码方式,当一个存储器读写总线事务到达PCI总线时,在这条总线上的所有PCI设备将进行地址译码,如果当前总线事务使用的地址在某个PCI设备的BAR空间中时,该PCI设备将使 ...
- 理解Android DecorView
一.DecorView为整个Window界面的最顶层View. 二.DecorView只有一个子元素为LinearLayout.代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域. 三. ...