1189: [HNOI2007]紧急疏散evacuate

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3658  Solved: 1069
[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

5 5
XXXXX
X...D
XX.XX
X..XX
XXDXX

Sample Output

3

HINT

2015.1.12新加数据一组,鸣谢1756500824

Source

黄学长的代码是跑不过的,具体看他blog下方的评论

其实只需要改一点即可,就是把门按时间进行拆点,每个点连到bfs跑出最短路的拆的那个点

门按时间拆的每一个点都向

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
#define p(x,y) (x-1)*m+y
using namespace std;
inline int read(){int x=0;int f=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}return x*f;
}
const int MAXN=1e5+10;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
struct node{int y,next,flow,back;
}e[MAXN];
int linkk[MAXN],level[10000],q[MAXN],head,tail,len,s,t,d[MAXN][2],dis[500][25][25],n,m,sum,mp[30][30],door=1;
inline void insert(int x,int y,int f){//cout<<x<<' '<<y<<endl;e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].flow=f;e[len].back=len+1;e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].flow=0;e[len].back=len-1;
}
inline bool getlevel(){head=tail=0;memset(level,-1,sizeof(level));q[++tail]=s;level[s]=0;while(head<tail){int tn=q[++head];for(int i=linkk[tn];i;i=e[i].next){if(level[e[i].y]==-1&&e[i].flow){level[e[i].y]=level[tn]+1;q[++tail]=e[i].y;}}}return level[t]>=0;
}
inline int getmaxflow(int x,int flow){int f=0,d;if(x==t) return flow;for(int i=linkk[x];i;i=e[i].next){if(level[e[i].y]==level[x]+1&&e[i].flow){if(d=getmaxflow(e[i].y,min(e[i].flow,flow-f))){f+=d;e[i].flow-=d;e[e[i].back].flow+=d;if(f==flow) return f;}}}if(f==0) level[x]=-1;return f;
}
inline int dinic(){int ans=0,d;while(getlevel()){while(d=getmaxflow(s,inf)) ans+=d;}return ans;
}
inline void bfs(int k,int x,int y){head=tail=0;d[++tail][0]=x;d[tail][1]=y;dis[k][x][y]=0;while(head<tail){int xx=d[++head][0];int yy=d[head][1];for(int i=0;i<4;i++){int tx=xx+dx[i];int ty=yy+dy[i];if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]!=1||dis[k][tx][ty]!=inf) continue;dis[k][tx][ty]=dis[k][xx][yy]+1;d[++tail][0]=tx;d[tail][1]=ty;}}
}
inline bool check(int mid){s=0;t=n*m+1+mid*door;memset(linkk,0,sizeof(linkk));len=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(mp[i][j]==1) insert(s,p(i,j),1);}}for(int i=2;i<=door;i++){for(int j=1;j<=mid;j++){insert(n*m+(i-2)*mid+j,t,1);if(j!=mid) insert(n*m+(i-2)*mid+j,n*m+(i-2)*mid+j+1,inf);}}for(int k=2;k<=door;k++){for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(dis[k][i][j]<=mid&&mp[i][j]==1) insert(p(i,j),n*m+(k-2)*mid+dis[k][i][j],1);}}}int ans=dinic();//cout<<mid<<' '<<ans<<' '<<sum<<endl;return ans==sum;
}
int main(){n=read();m=read();for(int i=1;i<=n;i++){char ch[30];scanf("%s",ch+1);for(int j=1;j<=m;j++){if(ch[j]=='X') mp[i][j]=0;if(ch[j]=='.') mp[i][j]=1,sum++;if(ch[j]=='D') mp[i][j]=++door;}}for(int i=2;i<=door;i++){for(int j=1;j<=n;j++){for(int k=1;k<=m;k++){dis[i][j][k]=inf;}}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(mp[i][j]>1) bfs(mp[i][j],i,j);}}int l=0;int r=400;int mn=-1;while(l<=r){int mid=(l+r)>>1;if(check(mid)) r=mid-1,mn=mid;else l=mid+1;}if(mn==-1) cout<<"impossible"<<endl;else cout<<mn<<endl;return 0;
}

  

时间+1连一条容量为inf的点,拆除来的点向汇点连一条容量为1的边即可

转载于:https://www.cnblogs.com/something-for-nothing/p/9012348.html

BZOJ 1189 HNOI2007 紧急疏散evacuate相关推荐

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

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

  2. bzoj1189 [HNOI2007]紧急疏散EVACUATE spfa+网络流+二分

    这个题是非常暴力的匹配问题. 首先最好想的思路是给每个人分门的决策, 每个人到每个门的距离直接暴力最短路即可 但不能算出一个门被多个人经过的情况 所以就有了暴力的想法,再给每个人.对每一个门分配一个时 ...

  3. bzoj1189 [HNOI2007]紧急疏散evacuate(二分答案+bfs+最大流判是否满流)

    首先bfs处理出每个人到每个门所需的时间.然后二分答案,对于所有人能到的所有门,建边,边权为1,从源点向所有人建边,边权为1,从所有门向汇点建边,边权为mid(最多出去mid个人),dinic跑最大流 ...

  4. bzoj 1189 紧急疏散 网络流

    二分答案,网络流判断 将每个门拆点,每个人连向每个门的dis~当前解 然后跑最大流,如果等于人数,即为可行解 #include<cstdio> #include<iostream&g ...

  5. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1435  Solv ...

  6. BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1386  Solved: 840 [Submit][Status][Discuss] Descrip ...

  7. BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)

    题目链接 把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序. 从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\) ...

  8. BZOJ 1190: [HNOI2007]梦幻岛宝珠

    好难的分层DP TAT 把WTY大爷的话读了好几遍,并不是很懂(然后就把代码抄了一遍) 话说这代码跑得略慢了....... #include<iostream> #include<c ...

  9. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  10. 有趣题目和认知合集(持续更新)

    写写对一些算法的理解,挂几个有意思的题,可能也会挂几个板子题 算法理解偏向于能懂即可,没有严格的证明 快乐几何 [1.2]Volatile Kite 点到直线 快乐搜与暴力 [2.4]Short Co ...

最新文章

  1. java web项目测试_java web项目怎么测试?
  2. 当你再面对大多数需求时能够说这些问题我以前做过,那你就。。。
  3. numpy-自定义ufunc函数和广播
  4. 【直播回放】中外大厂奇葩说:谁是技术圈的嘴炮王者?
  5. 【Linux】一步一步学Linux——Linux内核版本和发行版本(03)
  6. sync.Once 的前世今生
  7. YBTOJ洛谷P3292:幸运数字(线性基、点分治/倍增)
  8. HttpServletResponse.getWriter().print乱码,request.getHeader乱码,解决方法
  9. mikechen谈技术人成长的三大原则
  10. curl有php内存缓存,PHP CURL内存泄露的解决方法
  11. 按比例算出成绩 用c语言,Excel按指定比例生成学生总分,并迭代计算出各学科分数...
  12. C++ (void)_r;什么意思
  13. 树莓派 | 摄像头模块的使用方法
  14. 路由的几个基本概念-直连路由/网关路由/主机路由/网络路由/动态路由/静态路由/默认路由
  15. PHP实现微信网页登陆授权开发
  16. 格拉姆-施密特过程的程序实现
  17. 如何修改第三方DLL文件名
  18. Android开源 -- 开源的基于 Material Design设计的豆瓣的Android客户端“豆芽”
  19. [转载]微软下一代掌上操作系统Microsoft Windows Mobile Crossbow
  20. 纳米数据,足球比分,赛事数据接口api,足球数据接口

热门文章

  1. ω一致的故事和符号世界的对应——哥德尔读后之24
  2. paintComponent方法的一些小把戏
  3. Backend For Frontend 实践心得
  4. Win10播放视频卡顿怎么解决
  5. 淘宝直通车如何打造爆款,直通车爆款秘籍
  6. 300篇原创文背后的故事
  7. 【刷题篇】鹅厂文化衫问题
  8. 海思AI芯片(35xx):板端运行报错
  9. css3实现3d图片旋转效果
  10. Struts2 内部是如何工作的