Prison Break

时间限制: 1 Sec  内存限制: 128 MB
提交: 105  解决: 16
[提交][状态][讨论版]

题目描述

Scofild又要策划一次越狱行动,和上次一样,他已经掌握了整个监狱的地图,看守的位置,以及准备好了逃出监狱的出口。由于消息被其他监狱中的囚犯得知了,为了不泄露消息,他不得不将所有人带出监狱。 
这是一个月黑风高的夜晚。。。看守们都已经睡着,在没有罪犯打扰的情况下绝对不会醒来,即罪犯不能到达看守所在位置。在每一个空地中,都有一名罪犯,并且同一个空地,能容纳无穷多个罪犯。每个人都只能向东南西北四个方向移动。在地图中某些位置,有一些出口,当罪犯到达出口,就视为逃出监狱,并且出口每一秒钟最多能逃出1个罪犯。现在越狱行动开始。。。Scofild需要安排一个越狱计划,使得大家能尽快的逃出监狱。此时,监狱的监控发现了情况,监狱外的警察,将在T秒后到达现场,并封锁所有出口。现在Scofild想要知道所有人能否成功越狱,如果能,计算出所需的最短的越狱时间,使得最后一个人逃出监狱的时间尽量的短。

输入

第一行三个整数r,c,T(3 <= r, c <= 12) 
接下来r行字符,每行c列。‘.’表示一个空地,一开始该点有一名罪犯。‘X’表示警察的位置,并且他不能移动,罪犯也不能到达该点,否则他就会醒来并拉响警报。‘E’表示出口。

输出

1行,输出最少的越狱时间,如果在大批警察赶到之后还有人无法逃离,则输出“impossible”。

样例输入

5 5 3
XXEXX
X...X
E...X
X...E
XXXXX

样例输出

3
这道题也许很少有人会去想二分答案,因为我看到这题的是时候没什么思路,模型转换最基础的都不会,直到zyh老师讲了一遍才知道,主要还是构图问题十分严重,
可以这样构图,求出各人犯到出口的最短路,然后就等在那里,假设有几个分身,因为出口一次只能跑出去一个人所以人到了可以等在那里,然后从那个时刻开始,
可以发现 n时刻可以全跑出,那么>n的时刻绝对可以跑出,如果n时刻不能跑出,那么n-1时刻坑定不能跑出,所以具有二分性,如何判断能不能跑完呢?就是用二分图
最大匹配数去判断,将每个出口裂成mid时刻个点,如果最短时间是t则与裂成的点,表示t,t+1,...,mid所有点连一条边,表示任何这里时刻都可以跑出,这样复杂度
O(nmlogt)是可以过的。
 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std; typedef pair<int,int>fzy;
const int NN=*+; int n,m,T,ckt=,ckq=;
int dis[NN][NN],flag[NN*],fa[NN*];
char c[][];
bool boo[][];
int cb[][]={};
struct node
{
int x,y,flag;
}out[NN],qf[NN];
int cnt,head[NN*],next[],rea[]; void add(int u,int v)
{
cnt++;
next[cnt]=head[u];
head[u]=cnt;
rea[cnt]=v;
}
bool dfs(int u)
{
for (int i=head[u];i!=-;i=next[i])
{
int v=rea[i];
if (flag[v]==)
{
flag[v]=;
if (fa[v]==-||dfs(fa[v]))
{
fa[v]=u;
return ;
}
}
}
return ;
}
void bfs(int i)
{
queue<fzy>q;
queue<int>p;
memset(boo,,sizeof(boo));
boo[qf[i].x][qf[i].y]=;
while (!q.empty()) q.pop();
while (!p.empty()) p.pop();
q.push(make_pair(qf[i].x,qf[i].y));
p.push();
while (!q.empty())
{
fzy now=q.front();
int vis=p.front();
q.pop(),p.pop();
int x=now.first,y=now.second;
if (c[x][y]=='E') dis[i][cb[x][y]]=vis;
if (x->=&&c[x-][y]!='X'&&boo[x-][y]==)
{
boo[x-][y]=;
q.push(make_pair(x-,y));
p.push(vis+);
}
if (x+<=n&&c[x+][y]!='X'&&boo[x+][y]==)
{
boo[x+][y]=;
q.push(make_pair(x+,y));
p.push(vis+);
}
if (y->=&&c[x][y-]!='X'&&boo[x][y-]==)
{
boo[x][y-]=;
q.push(make_pair(x,y-));
p.push(vis+); }
if (y+<=m&&c[x][y+]!='X'&&boo[x][y+]==)
{
boo[x][y+]=;
q.push(make_pair(x,y+));
p.push(vis+);
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&T);
memset(dis,-,sizeof(dis));
for (int i=;i<=n;i++)
scanf("%s",c[i]+);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (c[i][j]=='E')
{
out[++ckt].flag=ckt;
out[ckt].x=i,out[ckt].y=j;
cb[i][j]=ckt;
}
else if (c[i][j]=='.')
{
qf[++ckq].x=i;
qf[ckq].y=j;
}
for (int i=;i<=ckq;i++) bfs(i);
int l=,r=T+;
while (l<r)
{
int mid=(l+r)/;
cnt=;
memset(head,-,sizeof(head));
for (int i=;i<=ckq;i++)
for (int j=;j<=ckt;j++)
if (dis[i][j]!=-)
for (int k=dis[i][j];k<=mid;k++)
add(i,(j-)*mid+k);
int res=;
memset(fa,-,sizeof(fa));
for (int i=;i<=ckq;i++)
{
memset(flag,,sizeof(flag));
res+=dfs(i);
}
if (res==ckq) r=mid;
else l=mid+;
}
if (l==)
{
cout<<<<endl;
return ;
}
if (l==T+) printf("impossible");
else printf("%d\n",l);
}

Prison Break的更多相关文章

  1. HDU 3681 Prison Break(BFS+二分+状态压缩DP)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  2. hdu 3681 Prison Break (TSP问题)

    Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  3. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  4. hdu3511 Prison Break 圆的扫描线

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3511 题目: Prison Break Time Limit: 10000/5000 MS ( ...

  5. HDU3681 Prison Break

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  6. 1254 - Prison Break

    1254 - Prison Break   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Mic ...

  7. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  8. hdu 3681 Prison Break

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:一个n*m的矩阵,'F'是起点.机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所 ...

  9. light oj 1254 - Prison Break 最短路

    题目大意:n个点m条边的有向图,q次询问c,s,t,表示汽车邮箱容量为c,求从起点s到终点t的最小费用.汽车在每个点可以加任意的油,每个点的单位油价为a[i]. 题目思路:利用最小费优先队列优化最短路 ...

随机推荐

  1. ascii codec can't decode byte 0xe8 in position 0:ordinal not in range(128) python代码报错

    import sys reload(sys) sys.setdefaultencoding('utf-8')

  2. 安装lvs过程

    linux我是最小化安装的mini,安装完成后搭建本地yum,首先安装Development Tools开发工具组 1)在各服务器上修改主机名: [root@LVS1 ~]# hostname LVS ...

  3. mysql:ip地址连接

    2. 为用户授权 授权格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码"; 2.1登录MYSQL(有ROOT权限),这里以ROO ...

  4. MySQL(十一)之触发器

    上一篇介绍的是比较简单的视图,其实用起来是相对比较简单的,以后有什么更多的关于视图的用法,到时候在自己补充.接下来让我们一起了解一下触发器的使用! 一.触发器概述 1.1.什么是触发器 触发器(Tri ...

  5. 分享45个android实例源码,很好很强大.收藏吧!!!

    andriod闹钟源代码 http://www.apkbus.com/android-20974-1-1.html android源码分享之指南针程序 http://www.apkbus.com/an ...

  6. Angular+ionic2 web端 启动程序出现短暂 白屏或黑屏 的处理小妙招

    在ionic2项目启动是会出现短暂的白屏或者黑屏,虽然很短,但是用户体验不太好.上网查了相关的资料,都是针对打包APP的解决办法,针对浏览器端使用的项目没有效果,所以自己写了样式,巧妙的避开这个问题, ...

  7. CloseableHttpClient 源码

    public abstract class CloseableHttpClient implements HttpClient, Closeable { private final Log log = ...

  8. Swing-JOptionPane对话框用法-入门

    对话框是GUI程序中常见的界面,通常用来反馈提示信息.告警或获取用户输入.比如这种: JOptionPane是Swing中的一个对话框类,它能够提供常见的绝大多数对话框效果,本文对这个类进行介绍.需要 ...

  9. 201521123122 《java程序设计》第八周实验总结

    201521123122 <java程序设计>第八周实验总结 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 List中指定元素的删除(题目4- ...

  10. 201521123064 《Java程序设计》第4周学习总结

    1. 本章学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. ① 以上周PTA实验"形状"为例,Circle类和Rectangle类中 ...