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. CakePHP中回调函数的使用

    我们知道模型主要是用来处理数据的,有时我们想在模型操作之前或之后做一些额外逻辑处理,这时候就可以使用回调函数. 回调函数有很多种,beforeFind,afterFind,beforeValidate ...

  2. 使用duplicateweedout

    mysql> explain extended select * from cities where id in (select phonecode from countries group b ...

  3. 「日常训练」 Counting Cliques(HDU-5952)

    题意与分析 题源:2016ACM/ICPC沈阳现场赛. 这题让我知道了什么是团,不过最恶心的还是这题的数据了,卡了无数次- - 解决方法是维护一个G数组,不能去遍历邻接矩阵.至少我改了这么一个地方就过 ...

  4. 苏醒的巨人----CSRF

    一.CSRF 跨站请求伪造(Cross-Site Request Forgery,CSRF)是指利用 受害者尚未失效的身份认证信息(cookie.会话等),诱骗其点 击恶意链接或者访问包含攻击代码的页 ...

  5. word record 4

    word record 4 pledge p le g vt. 保证,许诺 snowflake falke->n. 小薄片:火花 deputy de piu ti n. 代理人,代表 etch ...

  6. 复合词 (Compund Word,UVa 10391)

    题目描述: 题目思路: 用map保存所有单词赋键值1,拆分单词,用map检查是否都为1,即为复合词 #include <iostream> #include <string> ...

  7. mweb test

    目录 Markdown syntax guide and writing on MWeb Philosophy Notice Headers This is an <h1> tag Thi ...

  8. crt0.S(_main)代码分析

    crt0,S(_main)代码分析 --- 1. 设置sp寄存器地址 //设置SP栈指针 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG ...

  9. 【转】C++后台开发之我见

    工作也快两年了,偶然看到自己以前写过的一些技术博客,发现自己自毕业后一直没有更新过自己的技术博客,趁现在是刚过完春节快要回公司工作之际,谈谈我个人对后台开发的一些个人见解,希望能够对在校的学生或者刚刚 ...

  10. python中argparse库的使用教程链接

    这两篇文章详细介绍了argparse库的参数设置及使用包括位置参数与可选参数的用法 http://blog.csdn.net/guojuxia/article/details/44462381 htt ...