题目链接:紧急疏散

  这薄脊题我代码不知不觉就写长了……

  这道题二分答案显然,然后用最大流\(check\)即可。设当前二分的答案为\(x\),那么把每扇门拆成\(x\)个点,第\(i\)个代表在第\(i\)个时刻从这个门走出去。然后把每个空地往可以到达的们的相应时间连边就可以了。判一下这张图是否满流即可。

  然后我们就需要先求出每个空地到门的距离……注意途中不能经过另外的门,否则会被BZOJ上加强的数据给卡掉……

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define INF 1000000000
#define maxn 200010
#define maxm 1000010
#define N 24 using namespace std;
typedef long long llg; int zx[4]={1,-1,0,0},zy[4]={0,0,-1,1};
int n,m,nu[N][N],f[N*N][N*N],dor,tol,dep[maxn],d[maxn];
int head[maxn],next[maxm],to[maxm],c[maxm],tt,S,T;
char s[N][N]; bool w[N*N]; void link(int x,int y,int z){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
c[tt-1]=z; c[tt]=0;
} bool bfs(){
for(int i=1;i<=T;i++) dep[i]=-1;
int ld=0,rd=0; dep[d[rd++]=S]=1;
while(ld!=rd){
int u=d[ld++];
for(int i=head[u],v;v=to[i],i;i=next[i])
if(c[i] && dep[v]==-1) dep[v]=dep[u]+1,d[rd++]=v;
}
return dep[T]!=-1;
} int dfs(int u,int now){
if(!now) return 0;
if(u==T) return now;
int low=0,res;
for(int i=head[u],v;v=to[i],i;i=next[i])
if(c[i] && dep[v]==dep[u]+1){
res=dfs(v,min(now,c[i])); low+=res;
c[i]-=res; c[i^1]+=res; now-=res;
}
if(!low) dep[u]=-1;
return low;
} bool check(int x){
tt=1; S=tol*x+1; T=S+1;
for(int i=1;i<=tol;i++)
if(w[i])
for(int j=1;j<=x;j++){
link(tol*(j-1)+i,T,1);
if(j!=x) link(tol*(j-1)+i,tol*j+i,INF);
}
else{
link(S,i,1);
for(int j=1;j<=tol;j++)
if(w[j] && f[i][j]<=x) link(i,tol*(f[i][j]-1)+j,1);
}
int now=0; while(bfs()) now+=dfs(S,INF);
for(int i=1;i<=T;i++) head[i]=0;
return now==tol-dor;
} int dx[N*N],dy[N*N]; bool vis[N][N];
void getdis(int x,int y){
int u=nu[x][y]; if(w[u]) return;
rep(i,1,n) rep(j,1,m) vis[i][j]=0;
int ld=0,rd=0; dx[rd]=x,dy[rd++]=y; vis[x][y]=1;
while(ld!=rd){
int o=dx[ld],p=dy[ld++];
for(int k=0,i,j,v;k<4;k++){
i=o+zx[k],j=p+zy[k]; v=nu[i][j];
if(i>=1 && i<=n && j>=1 && j<=m){
if(vis[i][j]) continue;
if(s[i][j]!='X') f[u][v]=f[u][nu[o][p]]+1;
if(s[i][j]=='.') dx[rd]=i,dy[rd++]=j,vis[i][j]=1;
}
}
}
} int main(){
File("a");
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++)
if(s[i][j]!='X'){
nu[i][j]=++tol;
dor+=(w[tol]=(s[i][j]=='D'));
}
}
rep(i,1,tol) rep(j,1,tol) if(i!=j) f[i][j]=INF;
rep(i,1,n) rep(j,1,m) if(nu[i][j]) getdis(i,j);
int l=0,r=tol-dor+1,mid;
while(l!=r){
mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
if(l>tol-dor) printf("impossible");
else printf("%d",l);
return 0;
}

BZOJ 1189 【HNOI2007】 紧急疏散evacuate的更多相关文章

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

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

  2. bzoj 1189 [HNOI2007]紧急疏散evacuate 二分+网络流

    [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3626  Solved: 1059[Submit][St ...

  3. BZOJ 1189 [HNOI2007]紧急疏散evacuate

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

  4. bzoj 1189: [HNOI2007]紧急疏散evacuate 分层图最大流_拆点_二分

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

  5. 【BZOJ】1189: [HNOI2007]紧急疏散evacuate(二分+bfs+网络流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1189 表示完全不会QAQ.... 于是膜拜题解orz 二分时间........... 于是转换成判定 ...

  6. 1189: [HNOI2007]紧急疏散evacuate - BZOJ

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

  7. 1189: [HNOI2007]紧急疏散evacuate

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3831  Solved: 1119[Submit][Status][Discuss] Descript ...

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

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

  9. Bzoj1189 [HNOI2007]紧急疏散evacuate

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

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

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

随机推荐

  1. Pycharm模板添加默认信息

    我们在Pycharm中使用到python3.x版本的解释器,完全没有问题可以正常使用,但是有的时候多少会出现使用python2的时候 我们明明都把代码和文字注释了,为什么使用的时候还会报错呢?? 报错 ...

  2. 知道椭圆长轴,短轴长度,ab直线的长度知道且垂直于长轴。求ab的弧长。

    1:知道椭圆长轴,短轴长度,ab直线的长度知道且垂直于长轴.求ab的弦长.: https://jingyan.baidu.com/article/a378c960a5af27b3282830e6.ht ...

  3. idea安装插件

    方法1:file>settings>pulgins>browse repositories>输入要安装的插件>install 方法2:本地安装,如果在browse中没有找 ...

  4. Flask中'endpoint'(端点)的理解

    翻译整理自Stack Overflow:http://stackoverflow.com/questions/19261833/what-is-an-endpoint-in-flask 原文中用到了m ...

  5. 【转】 Oracle 用户权限管理方法

    sys;//系统管理员,拥有最高权限 system;//本地管理员,次高权限 scott;//普通用户,密码默认为tiger,默认未解锁 sys;//系统管理员,拥有最高权限 system;//本地管 ...

  6. logistics回归

    logistic回归的基本思想 logistic回归是一种分类方法,用于两分类问题.其基本思想为: a. 寻找合适的假设函数,即分类函数,用以预测输入数据的判断结果: b. 构造代价函数,即损失函数, ...

  7. js绘制圆形时钟

    纯js制作圆形时钟 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  8. JQuery表单元素过滤选择器

    此选择器主要是对所选择的表单元素进行过滤: 选择器 描述 返回 enabled 选择所有的可用的元素 集合元素 disabled 选择所有的不可用的元素 集合元素 checked 选择所有被选中的元素 ...

  9. keras load model 遇到 自定义函数 Lambda(lambda x: softmax(x, axis=1), NameError: global name 'softmax' is not defined

    问题 在定义模型的时候,自定义了一个函数 模型保存之后,load 模型的时候报错: 解决 load 模型的时候需要指定custom object 参考: https://faroit.github.i ...

  10. 使用 amcharts 和 highcharts 绘制多曲线时间趋势图的通用方法

    工作中用到, 这里分享一下. 可以使用 amcharts 和 highcharts 在同一坐标中绘制多个对比曲线图. 当然, 对图形没有过多装饰, 可以参考 API 文档: highcharts:   ...