「LuoguP3191」 [HNOI2007]紧急疏散EVACUATE(最大流
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
C++语言请用scanf(“%s”,s)读入!
题解
首先这只是90分代码并且已经手推出数据被卡 也许是代码问题也许是思路问题(遍历题解并没有同样的思路但是我真的调了好几个小时了要吐了
首先读题很容易想到二分答案
拆点,设空地< i.a >,< i.b > 门< d.a >,< d.b >,设二分的答案为k
从S到每个< i.a >连边为1
每个< i.a >向< i.b >连k,每个< d.a >向< d.b >连k
然后从每个门开始dfs dfs的第一个空地< i.b >向< d.a >连k,之后按dfs序 后扫到的空地的< i2.b >向前一个的< i1.a >连k
最后每一个< d.b >向T连k
注意网络流的二分答案一般都要复原操作(把反边流量加到正边上 清空反边流量)
这道题真的恶心到呕吐 有朝一日过了我给你黑
丑到我都不想看的代码真的丑到哭泣
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=99999999;
char tu[27][27];
int n,m;
int flag=0;
void scan()
{
cin>>n>>m;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin>>tu[i][j];
return;
}
int s,t;
int num[27][27];
int ss;
bool sf[27][27];
int mx[5]={0,1,0,-1,0};
int my[5]={0,0,1,0,-1};
struct emm{
int e,f,v;
}a[1000007];
int h[807];
int tot=1;
void con(int x,int y,int l)
{
a[++tot].f=h[x];
h[x]=tot;
a[tot].e=y;
a[tot].v=l;
a[++tot].f=h[y];
h[y]=tot;
a[tot].e=x;
a[tot].v=0;
return;
}
/*
void dfss(int x,int y)
{
sf[x][y]=1;
for(int i=1;i<=4;++i)
{
x+=mx[i],y+=my[i];
if((tu[x][y]=='.'||tu[x][y]=='D')&&!sf[x][y])
{
con(num[x][y],ss,1);
//dfss(x,y);
}
x-=mx[i],y-=my[i];
}
return;
}
*/
int tag,peo=0;
void dfsss(int bx,int by,int x,int y,int k)
{
con(num[x][y]+m*n,num[bx][by],k);
int bbx=x,bby=y;
sf[x][y]=1;
for(int i=1;i<=4;++i)
{
x+=mx[i],y+=my[i];
if(tu[x][y]=='.'&&!sf[x][y])dfsss(bbx,bby,x,y,k);
x-=mx[i],y-=my[i];
}
return;
}
void build()
{
s=0,t=2*m*n+1;
int tim=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
num[i][j]=++tim;
num[0][0]=t;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='.'){
con(s,num[i][j],1);
peo++;
}
/*
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='D'||tu[i][j]=='.'){
memset(sf,0,sizeof(sf));
ss=num[i][j];
dfss(i,j);
}
*/
tag=tot;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='.'||tu[i][j]=='D')con(num[i][j],num[i][j]+m*n,-1);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='D'){
memset(sf,0,sizeof(sf));
dfsss(0,0,i,j,-1);
}
return;
}
void conn(int x,int y,int k)
{
//cout<<x<<" "<<y<<endl;
a[++tot].v=k;
a[++tot].v=0;
return;
}
void dfss(int bx,int by,int x,int y,int k)
{
conn(num[x][y]+m*n,num[bx][by],k);
int bbx=x,bby=y;
sf[x][y]=1;
for(int i=1;i<=4;++i)
{
x+=mx[i],y+=my[i];
if(tu[x][y]=='.'&&!sf[x][y])dfss(bbx,bby,x,y,k);
x-=mx[i],y-=my[i];
}
return;
}
void adbuild(int k)
{
//cout<<"adbuild"<<k<<endl;
//cout<<"a"<<endl;
tot=tag;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='.'||tu[i][j]=='D')conn(num[i][j],num[i][j]+m*n,k);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(tu[i][j]=='D'){
memset(sf,0,sizeof(sf));
dfss(0,0,i,j,k);
}
return;
}
queue<int>q;
int d[807];
inline bool bfs()
{
memset(d,0,sizeof(d));
d[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=h[x];i;i=a[i].f)
if(!d[a[i].e]&&a[i].v)
{
d[a[i].e]=d[x]+1;
q.push(a[i].e);
}
}
return d[t];
}
int dfs(int x,int al)
{
if(x==t||!al)return al;
int fl=0;
for(int i=h[x];i;i=a[i].f)
if(d[a[i].e]==d[x]+1&&a[i].v)
{
if(flag)cout<<x<<" "<<a[i].e<<endl;
int f=dfs(a[i].e,min(a[i].v,al));
if(f)
{
fl+=f;
al-=f;
a[i].v-=f;
a[i^1].v+=f;
if(!al)break;
}
}
if(!fl)d[x]=-1;
return fl;
}
void erfen(int l,int r)
{
//cout<<"l="<<l<<" r="<<r<<endl;
if(l==r){if(r==peo+1)cout<<"impossible"<<endl;else cout<<l<<endl;return;}
int mid=(l+r)/2;
if(mid==6)flag=1;else flag=0;
for(int i=2;i<=tag;i+=2){a[i].v+=a[i^1].v;a[i^1].v=0;}
adbuild(mid);
int ans=0;
while(bfs()){ans+=dfs(s,INF);if(flag)cout<<ans<<endl;}
//cout<<"mid="<<mid<<" ans="<<ans<<endl;
if(ans==peo)erfen(l,mid);
else erfen(mid+1,r);
return;
}
int main()
{
//freopen("a.in","r",stdin);
scan();
build();
erfen(0,peo+1);
return 0;
}
出锅数据:
4 4
...D
.XX.
....
XD.X
手推ans=6 程序输出7
再 也 不 想 调 了
如果有dalao能看穿的话就 救救孩子
深鞠躬QAQ
「LuoguP3191」 [HNOI2007]紧急疏散EVACUATE(最大流的更多相关文章
- BZOJ1189:[HNOI2007]紧急疏散EVACUATE(最大流,枚举)
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- P3191 [HNOI2007]紧急疏散EVACUATE(费用流)
P3191 [HNOI2007]紧急疏散EVACUATE 费用流+卡常优化 我们只关心一个人通过门时的时间,在空地的行走时间可以分层维护 于是根据时间分层,到门的时候再计算代价,即代价$=$层数 每经 ...
- BZOJ1189: [HNOI2007]紧急疏散evacuate 二分+最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1132 Solved: 412[Submi ...
- 【二分答案】【最大流】[HNOI2007]紧急疏散EVACUATE
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- Bzoj1189 [HNOI2007]紧急疏散evacuate
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 715 Descr ...
- [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- BZOJ 1189: [HNOI2007]紧急疏散evacuate( BFS + 二分答案 + 匈牙利 )
我们可以BFS出每个出口到每个人的最短距离, 然后二分答案, 假设当前答案为m, 把一个出口拆成m个表示m个时间, 点u到出口v的距离为d, 那么u->v的[d, m]所有点连边, 然后跑匈牙利 ...
- 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 ...
随机推荐
- 社区发现(Community Detection)算法
作者: peghoty 出处: http://blog.csdn.net/peghoty/article/details/9286905 社区发现(Community Detection)算法用来发现 ...
- RabbitMQ核心组件及应用场景
一.适用场景 1.解耦 2.最终一致性 3.广播 4.错峰与流控(秒杀业务用于流量削峰场景) 秒杀场景 二.核心组件,关键点(交换器.队列.绑定) AMPQ消息路由必要三部分:交换器.队列.绑定. J ...
- P1067 多项式输出 (模拟)
题目描述 一元nn次多项式可用如下的表达式表示: 其中,a_i x^i 称为i次项,ai 称为i次项的系数.给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式: 多项式中自变量 ...
- ThreadGroup
http://blog.csdn.net/a352193394/article/details/39323427
- Python3:urllib模块的使用
Python3:urllib模块的使用1.基本方法 urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=N ...
- Spring在Bean中注入集合
以下内容引用自http://wiki.jikexueyuan.com/project/spring/injecting-collection.html: 如果你想传递多个值,如Java Collect ...
- 邁向IT專家成功之路的三十則鐵律 鐵律一:IT人生存之道-柔
老子在道德經裡頭曾提到:「天下之至柔,馳聘天下之至堅」,又說:「堅強者死之徒,柔弱者生之徒」.其實人在面對世間的萬事萬物都是一樣的,只是當我們學習將這個至理套用在IT的工作職場時,將可以讓我們在這條崎 ...
- BUPT复试专题—中位数(2014-2)
题目描述 给定一个长度为N的非降数列,求数列的中位数.中位数:当数列的项数N为奇数吋,处于中间位置的变最值即为中位数:当N 为偶数时,中位数则为处于中间位置的两个数的平均数. 输入 输入数据第一行 ...
- C#如何设置控件水平对齐,垂直对齐
如果要设置一些控件垂直对齐,点击这个按钮 如果要设置水平对齐,则点击这个按钮,选中控件之后点击左对齐(多个按钮都试下吧,总归能对齐到你要的效果的)
- CSS样式布局入门介绍,非常详尽
转载自:http://wenboxz.com/archives/try-css-layout.html/