【题目链接】 http://poj.org/problem?id=3057

【题目大意】

  给出一个迷宫,D表示门,.表示人,X表示不可通行,
  每个门每时间单位只允许一个人通过,
  每个人移动一格的为一时间单位的时间,
  问所有人逃离这个迷宫的最小时间

【题解】

  我们首先对于每个门进行搜索,求出其到每个人的最短时间,
  之后我们将每扇门对于人来拆点,分别为这个人第几秒通过这个门
  将拆点后的门对所有人做一遍顺序二分图匹配
  匹配最终完成的时间的门是其第几个拆点那么时间就是第几秒

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAX_V=10000;
int V,match[MAX_V];
vector<int> G[MAX_V];
bool used[MAX_V];
void add_edge(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v){
used[v]=1;
for(int i=0;i<G[v].size();i++){
int u=G[v][i],w=match[u];
if(w<0||!used[w]&&dfs(w)){
match[v]=u;
match[u]=v;
return 1;
}
}return 0;
}
const int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};
const int MAX_X=12,MAX_Y=12;
int X,Y;
char field[MAX_X][MAX_X+1];
vector<int> dX,dY;
vector<int> pX,pY;
int dist[MAX_X][MAX_Y][MAX_X][MAX_Y];
void bfs(int x,int y,int d[MAX_X][MAX_Y]){
queue<int> qx,qy;
d[x][y]=0;
qx.push(x);
qy.push(y);
while(!qx.empty()){
x=qx.front(); qx.pop();
y=qy.front(); qy.pop();
for(int k=0;k<4;k++){
int x2=x+dx[k],y2=y+dy[k];
if(0<=x2&&x2<X&&0<=y2&&y2<Y&&field[x2][y2]=='.'&&d[x2][y2]<0){
d[x2][y2]=d[x][y]+1;
qx.push(x2);
qy.push(y2);
}
}
}
}
void solve(){
int n=X*Y;
dX.clear(); dY.clear();
pX.clear(); pY.clear();
memset(dist,-1,sizeof(dist));
for(int x=0;x<X;x++){
for(int y=0;y<Y;y++){
if(field[x][y]=='D'){
dX.push_back(x);
dY.push_back(y);
bfs(x,y,dist[x][y]);
}else if(field[x][y]=='.'){
pX.push_back(x);
pY.push_back(y);
}
}
}
int d=dX.size(),p=pX.size();
for(int i=0;i<=n*d+p;i++)G[i].clear();
for(int i=0;i<d;i++){
for(int j=0;j<p;j++){
if(dist[dX[i]][dY[i]][pX[j]][pY[j]]>=0){
for(int k=dist[dX[i]][dY[i]][pX[j]][pY[j]];k<=n;k++){
add_edge((k-1)*d+i,n*d+j);
}
}
}
}
if(p==0){
puts("0");
return;
}
int num=0;
memset(match,-1,sizeof(match));
for(int v=0;v<n*d;v++){
memset(used,0,sizeof(used));
if(dfs(v)){
if(++num==p){
printf("%d\n",v/d+1);
return;
}
}
}puts("impossible");
}
int T;
void init(){
scanf("%d%d",&X,&Y);
for(int i=0;i<X;i++)scanf("%s",field[i]);
}
int main(){
scanf("%d",&T);
while(T--){
init();
solve();
}return 0;
}

POJ 3057 Evacuation(二分图匹配+BFS)的更多相关文章

  1. TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs

    题意:见挑战230页 #include <iostream> #include <cstdio> #include <cstring> #include <c ...

  2. POJ 3057 Evacuation 二分图匹配

    每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:10240000 ...

  3. POJ 3057 Evacuation (二分匹配)

    题意:给定一个图,然后有几个门,每个人要出去,但是每个门每个秒只能出去一个,然后问你最少时间才能全部出去. 析:初一看,应该是像搜索,但是怎么保证每个人出去的时候都不冲突呢,毕竟每个门每次只能出一个人 ...

  4. POJ3057 Evacuation 二分图匹配+最短路

    POJ3057 Evacuation 二分图匹配+最短路 题目描述 Fires can be disastrous, especially when a fire breaks out in a ro ...

  5. [poj] 3057 Evacuation

    原题 题目大意 墙壁"X",空区域(都是人)".", 门"D". 人向门移动通过时视为逃脱,门每秒能出去一个人,人可以上下左右移动,墙阻止移 ...

  6. POJ 1274 裸二分图匹配

    题意:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶,告诉每头奶牛愿意产奶的牛棚编号,求出最多能分配到的牛栏的数量. 分析:直接二分图匹配: #include<stdio.h> #includ ...

  7. POJ 2446 Chessboard (二分图匹配)

    题意 在一个N*M的矩形里,用1*2的骨牌去覆盖该矩形,每个骨牌只能覆盖相邻的两个格子,问是否能把每个格子都盖住.PS:有K个孔不用覆盖. 思路 容易发现,棋盘上坐标和为奇数的点只会和坐标和为偶数的点 ...

  8. POJ 3057 Evacuation(二分匹配)

    分析: 这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性. t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d ...

  9. POJ 3057 Evacuation 二分+最大流

    Evacuation 题目连接: http://poj.org/problem?id=3057 Description Fires can be disastrous, especially when ...

随机推荐

  1. 解决display:inline-block;行内块元素出现空白空隙问题

     给他的父元素加:font-size:0px;,   ul { font-size:0px;} li { font-size:16px;}

  2. Python学习-前台开发-ajax操作

    概述 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用 一个简单操作需要 ...

  3. [转载]有关如何入门ACM

    来源: 吴垠的日志 一些题外话 首先就是我为什么要写这么一篇日志.原因很简单,就是因为前几天有个想起步做ACM人很诚恳的问我该如何入门.其实就现在而言,我并不是很想和人再去讨论这样的话题,特别是当我发 ...

  4. 阻塞&&非阻塞

    读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回.但是从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调 ...

  5. (总结)Nginx使用的php-fpm的两种进程管理方式及优化

    PS:前段时间配置php-fpm的时候,无意中发现原来它还有两种进程管理方式.与Apache类似,它的进程数也是可以根据设置分为动态和静态的. php-fpm目前主要又两个分支,分别对应于php-5. ...

  6. docker 生成新的镜像

    下载了ubuntu的初始化镜像,但是没有网络安装包,安装了字后,如果生成新的镜像 sudo docker commit -m "add ifconfig/ping package" ...

  7. [bzoj5287] [HNOI2018]毒瘤

    题目描述 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和.毒瘤考虑了n ...

  8. 2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16)

    A.The game of Osho(sg函数+二项展开) 题意: 一共有G个子游戏,一个子游戏有Bi, Ni两个数字.两名玩家开始玩游戏,每名玩家从N中减去B的任意幂次的数,直到不能操作判定为输.问 ...

  9. [Codeforces 1027 F] Session in BSU [并查集维护二分图匹配问题]

    题面 传送门 思路 真是一道神奇的题目呢 题目本身可以转化为二分图匹配问题,要求右半部分选择的点的最大编号最小的一组完美匹配 注意到这里左边半部分有一个性质:每个点恰好连出两条边到右半部分 那么我们可 ...

  10. 忽略node_modules目录

    如上图所示添加node_modules目录到忽略文件列表里面,点击应用就可以了.