http://poj.org/problem?id=3057

题目大意:

.为人,D为门,X为障碍,门每秒只能出去一个人,问多少秒出光。

如果无法出光输出impossible。

————————————————

首先bfs处理出来每个人到每个门的最短距离。

然后枚举时间,将时间与门作为二元组(或者理解为是make_pair也行)

当(当前时间)>=(该人到该门的时间),就把(这个人)与(这个门和当前时间的二元组)连起来。

然后二分图匹配找到匹配数比较和人数相不相等即可。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int NUM1=;
const int NUM2=;
const int TP=NUM2*;
const int SUM=NUM1*TP;
const int INF=;
int dx[]={,-,,};
int dy[]={,,-,};
int cnt=;
int p[NUM1][TP];
struct pair{
int fi;
int se;
}turn[SUM];
int pii(int a,int b){
if(p[a][b])return p[a][b];
cnt++;
turn[cnt].fi=a;
turn[cnt].se=b;
return p[a][b]=cnt;
}
int mp[][],dis[][],pos[][];
int to[NUM1][NUM2];
bool BFS(int xx,int yy,int r,int c){
for(int i=;i<=r;i++){
for(int j=;j<=c;j++){
dis[i][j]=INF;
}
}
queue<int>q1,q2;
q1.push(xx);q2.push(yy);
dis[xx][yy]=;
bool ok=;
while(!q1.empty()){
int x=q1.front(),y=q2.front();
q1.pop();q2.pop();
if(mp[x][y]>){
to[pos[xx][yy]][mp[x][y]]=dis[x][y];
ok=;
continue;
}
for(int i=;i<;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx>r||ny>c||nx<||ny<||mp[nx][ny]==-)continue;
if(dis[nx][ny]>dis[x][y]+){
dis[nx][ny]=dis[x][y]+;
q1.push(nx);q2.push(ny);
}
}
}
return ok;
}
bool vis[TP],a[NUM1][TP];
int shu[TP];
bool dfs(int i){
for(int j=;j<=cnt;j++){
if(a[i][j]&&!vis[j]){
vis[j]=;
if(!shu[j]||dfs(shu[j])){
shu[j]=i;
return ;
}
}
}
return ;
}
int num1,num2;
bool pan(int t){
memset(shu,,sizeof(shu));
int ans=;
for(int i=;i<=num1;i++){
memset(vis,,sizeof(vis));
if(dfs(i))ans++;
}
if(ans!=num1)return ;
return ;
}
void restart(){
cnt=;
num1=;
num2=;
memset(a,,sizeof(a));
memset(p,,sizeof(p));
memset(to,,sizeof(to));
memset(mp,,sizeof(mp));
memset(pos,,sizeof(pos));
return;
}
int main(){
int N;
cin>>N;
while(N--){
restart();
int r,c;
cin>>r>>c;
for(int i=;i<=r;i++){
for(int j=;j<=c;j++){
char ch;cin>>ch;
if(ch=='X')mp[i][j]=-;
else if(ch=='.'){
num1++;
pos[i][j]=num1;
}else mp[i][j]=;
}
}
for(int i=;i<=r;i++){
for(int j=;j<=c;j++){
if(mp[i][j]==){
num2++;
mp[i][j]=num2;
}
}
}
bool ha=;
for(int i=;i<=r;i++){
for(int j=;j<=c;j++){
if(!mp[i][j]){
if(!BFS(i,j,r,c)){
cout<<"impossible"<<endl;
ha=;
break;
}
}
}
if(ha)break;
}
if(ha)continue;
for(int i=;;i++){
for(int j=;j<=num1;j++){
for(int k=;k<=num2;k++){
if(to[j][k]&&to[j][k]<=i){
a[j][pii(k,i)]=;
}
}
}
if(pan(i)){
cout<<i<<endl;
break;
}
}
}
return ;
}

POJ3057:Evacuation——题解的更多相关文章

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

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

  2. POJ 3057 Evacuation 题解

    题目 Fires can be disastrous, especially when a fire breaks out in a room that is completely filled wi ...

  3. Emergency Evacuation 题解

    The Japanese government plans to increase the number of inbound tourists to forty million in the yea ...

  4. POJ3057 Evacuation(二分图最大匹配)

    人作X部:把门按时间拆点,作Y部:如果某人能在某个时间到达某门则连边.就是个二分图最大匹配. 时间可以二分枚举,或者直接从1枚举时间然后加新边在原来的基础上进行增广. 谨记:时间是个不可忽视的维度. ...

  5. Evacuation,题解

    题目: 题意: 有人,门(只有边上有,且1s只能出去一个人),和墙,每s人可移动一个格子,问多少秒所有人可以逃出,逃不出输出“impossible” 分析: 首先,我们先想着样一个问题,如果这个人在某 ...

  6. Emergency Evacuation,题解

    题目: 题意: 在某一秒,每个人可以进行一个移动:去旁边座位,去过道,在过道向出口走,求最少多少秒可以让所有人离开(具体如图和样例). 分析: 首先,我们先考虑简单的,只考虑出口前有什么事件发生:1. ...

  7. Codeforces Gym 100002 E "Evacuation Plan" 费用流

    "Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  8. POJ 3057 Evacuation 二分+最大流

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

  9. POJ2175:Evacuation Plan(消负圈)

    Evacuation Plan Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 5665Accepted: 1481Special J ...

随机推荐

  1. 天嵌IMX6开发板测试-第一篇

    1.看下开发板介绍 品牌: 天嵌 CPU型号: NXP i.MX6Q 架构: Cortex_A9 主频: *1GHz 内存: 2GB DDR3 存储: 8GB eMMC FLA(64GB可扩) 2. ...

  2. Oracle TDE的学习

    TDE的开启和关闭 设置wallet目录,在参数文件sqlnet.ora中,按照下面的格式加入信息 # Oracle Advanced Security Transparent Data Encryp ...

  3. linux-centos6②

  4. <cassert>

    文件名:  <cassert> (assert.h) 这是一个C语言的诊断库,assert.h文件中定义了一个可作为标准调试工具的宏函数: assert ; 下面介绍这个宏函数:asser ...

  5. [Install] TeamViewer

    安装TeamViwer 1. $ sudo apt-get -f install 2. 使用gdebi安装TeamViwer. 所以先安装gdebi package. $ sudo apt-get i ...

  6. Educational Codeforces Round 32 Problem 888C - K-Dominant Character

    1) Link to the problem: http://codeforces.com/contest/888/problem/C 2) Description: You are given a ...

  7. Mysql-表和字段操作

    1.查看表 show tables; 2.创建表 create table test( id int primary key auto_increment, name varchar(40) not ...

  8. Document对象内容集合

    document 文挡对象 - JavaScript脚本语言描述———————————————————————注:页面上元素name属性和JavaScript引用的名称必须一致包括大小写否则会提示你一 ...

  9. “Hello World!”团队第三周召开的第一次会议

    今天是我们团队“Hello World!”团队第三周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...

  10. 2017-2018-2 20172314 『Java程序设计』课程 结对编程练习_四则运算

    相关过程截图 截图为我负责的部分关于计算的测试 关键代码解释 根据代码中的部分解释,这部分代码实现了结果的整数和分数的输出,如果算出的结果为一个真分数,就输出真分数的形式,如果结果为整数,就输出整数形 ...