1189: [HNOI2007]紧急疏散evacuate

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1155  Solved: 420
[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
 
思路:
我是用二分匹配AC的,若从门走不可以走到所有空地,那么输出impossible,否则一定可以走出去。假设一个人走到门A处最少用时s,那么这个人可以从门A出去的时间为s、s+1、s+2等,由于每秒只能从一个门走出一个人,那么就是匹配关系了,左边是人,右边是在时间1s、2s、3s等时的门,从小到大匹配,当时间t时达到最大匹配则最少时间为t。
 
在网上看别人代码,大多数是最大流,st连所有人,流量1,所有人连在时间t内可以走到的门,流量1,所有门连end,流量t,二分t即可。
 
好像所有二分图都可以转化成网络流??。。
 
二分匹配代码(网络流没敲不贴了):

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 25
#define inf 999999999 int n, m;
char map[N][N];
int c[N][N]; struct node{
int x, y, d;
node(){}
node(int a,int b,int c){
x=a;y=b;d=c;
}
}a[N*]; struct dd{
int id, dis;
dd(){ }
dd(int a,int b){
id=a;dis=b;
}
}b[N*][]; bool cmp(dd a,dd b){
return a.dis<b.dis;
} int xx[]={,-,,};
int yy[]={,,,-};
bool visited[N][N];
bool V[N][N]; void bfs(int id){
queue<node>Q;
Q.push(a[id]);
memset(visited,false,sizeof(visited));
visited[a[id].x][a[id].y]=true;
node p, q;
int i;
int cnt=;
while(!Q.empty()){
p=Q.front();Q.pop();
for(i=;i<;i++){
q.x=p.x+xx[i];
q.y=p.y+yy[i];
if(q.x>=&&q.x<n&&q.y>=&&q.y<m&&map[q.x][q.y]=='.'&&!visited[q.x][q.y]){
q.d=p.d+;
Q.push(q);
b[id][cnt++]=dd(c[q.x][q.y],q.d);
V[q.x][q.y]=visited[q.x][q.y]=true;
}
}
}
} bool vis[];
int from[];
vector<int>ve[]; int march(int u){
int i, v;
for(i=;i<ve[u].size();i++){
v=ve[u][i];
if(!vis[v]){
vis[v]=true;
if(from[v]==-||march(from[v])){
from[v]=u;
return ;
}
}
}
return ;
} main()
{
int i, j, k;
while(scanf("%d %d",&n,&m)==){
for(i=;i<n;i++) scanf("%s",map[i]);
int temp=, cnt=;
for(i=;i<n;i++){
for(j=;j<m;j++){
if(map[i][j]=='.'){
c[i][j]=temp++;
}
else if(map[i][j]=='D'){
a[cnt++]=node(i,j,);
}
}
}
memset(V,false,sizeof(V));
for(i=;i<cnt;i++){
bfs(i);
}
int ff=;
for(i=;i<n;i++){
for(j=;j<m;j++){
if(!V[i][j]&&map[i][j]=='.'){
ff=;
}
}
}
if(!ff){
printf("impossible\n");continue;
}
for(i=;i<cnt;i++) sort(b[i],b[i]+temp,cmp);
for(i=;i<temp;i++) ve[i].clear();
int t=;
while(){
for(i=;i<cnt;i++){
for(j=;j<temp;j++){
if(b[i][j].dis<=t){
ve[b[i][j].id].push_back(i+cnt*(t-));
}
else break;
}
}
memset(from,-,sizeof(from));
int f=;
for(i=;i<temp;i++){
memset(vis,false,sizeof(vis));
if(!march(i)){
f=;break;
}
}
if(f) break;
t++;
}
printf("%d\n",t);
}
}

BZOJ 1189 二分匹配 || 最大流的更多相关文章

  1. bzoj 1189 二分+最大流

    题目传送门 思路: 先预处理出每个人到每扇门的时间,用门作为起点进行bfs处理. 然后二分时间,假设时间为x,将每扇门拆成1到x,x个时间点,表示这扇门有几个时间点是可以出去的.对于一扇门,每个时间点 ...

  2. bzoj 1189 二分+最大流判定

    首先我们可以二分一个答案时间T,这样就将最优性问题 转化为了判定性问题.下面我们考虑对于已知的T的判定 对于矩阵中所有的空点bfs一次,得出来每个点到门的距离, 然后连接空点和每个能在t时间内到达的门 ...

  3. POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24081   Accepted: 106 ...

  4. poj 1247 The Perfect Stall 裸的二分匹配,但可以用最大流来水一下

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16396   Accepted: 750 ...

  5. hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...

  6. D唐纳德和他的数学老师(华师网络赛)(二分匹配,最大流)

    Time limit per test: 1.0 seconds Memory limit: 256 megabytes 唐纳德是一个数学天才.有一天,他的数学老师决定为难一下他.他跟唐纳德说:「现在 ...

  7. HDU 3081 Marriage Match II 最大流OR二分匹配

    Marriage Match IIHDU - 3081 题目大意:每个女孩子可以和没有与她或者是她的朋友有过争吵的男孩子交男朋友,现在玩一个游戏,每一轮每个女孩子都要交一个新的男朋友,问最多可以玩多少 ...

  8. BZOJ 1191: [HNOI2006]超级英雄Hero 二分匹配

    1191: [HNOI2006]超级英雄Hero Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或 ...

  9. bzoj 3130 [Sdoi2013]费用流(二分,最大流)

    Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...

随机推荐

  1. NPOI分层导出

    using NPOI.HSSF.UserModel; using NPOI.POIFS.FileSystem; using org.in2bits.MyXls; using System; using ...

  2. Swift_1基础

    // swift中导入类库使用import,不再使用<>和""import Foundation // 输出print("Hello, World!" ...

  3. SLAM前端技术选择思考

    以前是专门做室内定位技术研究的,先后学习和分析了多种基于电磁的室内定位技术,如WiFi指纹定位(先后出现过RSSI.CTF.CIR多种指纹特征).WiFi ToF定位.低功耗蓝牙BLE以及iBeaco ...

  4. Mifare系列6-射频卡与读写器的通信(转)

    文/闫鑫原创转载请注明出处http://blog.csdn.net/yxstars/article/details/38085415 1. 复位应答(Answer to request) 读写器呼叫磁 ...

  5. QAbstractItemView::setRootIndex(const QModelIndex & index) 失效

    问题: 在逻辑中使用了, QAbstractItemView::setRootIndex(const QModelIndex & index), 第一次设置生效, view 进入了model ...

  6. iOS - QRCode 二维码

    1.QRCode 在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing. 这两大组件我们都有用过,这里总结下各自的缺点: 1.ZBar 在扫描 ...

  7. HTML5 十大新特性(七)——拖放API

    拖放API是H5专门为了鼠标拖放而新提供了7个事件,可以分成三个部分来讲. 一.拖动的源对象(source)可以触发的事件 dragstart:拖动开始 drag:拖动进行中 dragend:拖动结束 ...

  8. Starting MySQL... ERROR! The server quit without updating PID file 解决办法

    来源:http://blog.rekfan.com/articles/186.html 我使用了第4条解决了问题 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的 ...

  9. log4net RemotingAppender 的配置

    Before you even start trying any of the alternatives provided, ask yourself whether you really need ...

  10. beat your own python env

    1,进入根目录,修改.bashrc,增加一个PATH目录 例如:alias cjtf='export PATH=/home/www/xxx/python_env:$PATH' 如果个人的机器的就不用a ...