题目大意:

在一个n*m的房间中 ‘X’为墙 ‘D’为门 ‘.’为人

门只存在与外围 人每秒钟只能向四连通区域走一步

门比较狭窄 每秒钟只能通过一个人

求所有人逃脱的最短时间 如果不可能则输出impossible

对每个门 广搜出能在这个门逃脱的人的逃出时间

将 对应各个时间的这个门 当做不同的点

即 若有d个门 p个人

时间1对应的门编号为 0~d-1

时间2对应的门编号为 d~2*d-1

时间t对应的门编号为 (t-1)*d~t*d-1

然后将人编号为 t*d~t*d+p-1

再将 对应时间的门的编号 与 对应时间在该门逃脱的人 连边

而一个人若能在 t 时间逃脱 那么同样可以在 t+1、t+2、t+3...时间逃脱

所以 对应时间到最晚时间的该门的编号 都可与 这个人连边

这样找到 各个时间的门 与 人 的最大匹配

时间从小到大 这样判断到最大匹配数恰好等于人数时说明此时所有人都可逃脱

#include <bits/stdc++.h>
using namespace std;
int n,m;
char G[][];
int mov[][]={,,,,,-,-,}; int dis[][][][];
// dis[x][y][i][j] 门的位置为xy 人的位置为ij 保存逃脱的最短用时
struct NODE { int x,y; };
vector <NODE> D, P; // D记录门的位置 P记录人的位置 const int E=***;
vector <int> e[E]; // 邻接表 bool bound(int x1,int y1) {
return x1< || x1>=n || y1< || y1>=m;
}
void bfs(int x1,int y1,int d[][]) {
// d为dis[x1][y1]对应的后两维
queue <NODE> q;
q.push((NODE){x1,y1});
d[x1][y1]=;
while(!q.empty()) {
NODE e=q.front(); q.pop();
for(int i=;i<;i++) {
int x2=e.x+mov[i][], y2=e.y+mov[i][];
if(bound(x2,y2) || d[x2][y2]!=-) continue;
if(G[x2][y2]!='.') continue;
d[x2][y2]=d[e.x][e.y]+;
q.push((NODE){x2,y2});
}
}
}
/**二分图最大匹配*/
bool vis[E];
int mat[E];
bool dfs(int u) {
vis[u]=;
for(int i=;i<e[u].size();i++) {
int v=e[u][i], d=mat[v];
if(d==- || !vis[d]&&dfs(d)) {
mat[u]=v, mat[v]=u;
return ;
}
}
return ;
}
int match(int d,int p) {
int res=;
memset(mat,-,sizeof(mat));
for(int i=;i<n*d;i++) // 时间从小到大 一旦找到最大匹配就是最快逃脱时间
if(mat[i]==-) {
memset(vis,,sizeof(vis));
if(dfs(i)) {
res++;
if(res==p) return i/d+;
/// 一旦匹配数等于人数 说明此时所有人都已匹配
}
}
return ;
}
/***/ void solve() {
memset(dis,-,sizeof(dis));
D.clear(), P.clear();
for(int i=;i<n;i++) {
for(int j=;j<m;j++)
if(G[i][j]=='D') {
D.push_back((NODE){i,j});
bfs(i,j,dis[i][j]);// 广搜出所有能到ij门的人的最短时间
} else if(G[i][j]=='.')
P.push_back((NODE){i,j});
} n*=m;
for(int i=;i<E;i++) e[i].clear();
int d=D.size(), p=P.size();
for(int i=;i<d;i++) {
for(int j=;j<p;j++) {
int t=dis[D[i].x][D[i].y][P[j].x][P[j].y];
if(t!=-) { // 说明最快t时间可以逃脱
for(int k=t;k<=n;k++) // 则t以上时间都可逃脱 连边
e[(k-)*d+i].push_back(n*d+j);
}
}
} if(p==) {
printf("0\n"); return;
}
int ans=match(d,p);
if(ans) printf("%d\n",ans);
else printf("impossible\n");
} int main()
{
int t; scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%s",G[i]);
solve();
} return ;
}

POJ Evacuation /// 二分图最大匹配的更多相关文章

  1. poj 2239 二分图最大匹配,基础题

    1.poj 2239   Selecting Courses   二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...

  2. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  3. poj 2724 二分图最大匹配

    题意: 会给出M个串,我们要做的就是将这M个串给清除了.对于任意两个串,若二进制形式只有一位不一样,那么这两个串可以在一次操作消除,否则每个操作只能消除一个串. 3 3 *01 100 011 可以代 ...

  4. Asteroids - poj 3041(二分图最大匹配问题)

      Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17258   Accepted: 9386 Description Be ...

  5. poj 2446 二分图最大匹配

    思路:由(i+j)为偶数的点向(i+j)为奇数的点建边.求一次最大匹配,若正好为空格数(不包含洞)的一半,即输出YES. #include<iostream> #include<cs ...

  6. poj 1469 二分图最大匹配

    就是最简单的最大匹配,没的说 #include<iostream> #include<cstdio> #include<cstring> #include<a ...

  7. poj 1469(二分图 最大匹配)

    这道题让我认识到了c++cin,cout确实会使其超时,还是我用的c printf吧 #include<cstdio> #include<iostream> #include& ...

  8. POJ 1719 二分图最大匹配(记录路径)

    Shooting Contest Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4097   Accepted: 1499 ...

  9. poj 3692 二分图最大匹配

    思路: 如果我们将认识的建边,求最大独立集就是互相不认识的人数.那么我们反过来,将不认识的建图,求最大独立集就是互相认识的人数. #include<cstdio> #include< ...

随机推荐

  1. elasticsearch中TermQuery查不到数据问题

    在java rest client中调用elasticsearch中的数据,精准匹配的termQuery查不到数据,这个问题是java rest client客户端自带的bug,换用matchPhra ...

  2. VS下使用VIM, Visual Studio 安装 VSvim插件 配置 及使用

    简介 VIM是一款很高效的编辑工具,所幸的是VS2012以后支持VIM的插件:VsVim.下面介绍插件的安装.配置及简单使用. 1. 下载安装 去官网下载,双击直接安装后,重新打开VS. https: ...

  3. 剑指offer——44连续子数组的最大和

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

  4. assignment of day four

    目录 1.Numeric type (1)integer (2)float Usefulness Define How to use 2.string type Use Define How to u ...

  5. 匈牙利算法实战codevs1022覆盖

    1022 覆盖    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 有一个N×M的单位方格中 ...

  6. RTL_PROCESS_MODULE_INFORMATION

    typedef struct _RTL_PROCESS_MODULE_INFORMATION { HANDLE Section; // Not filled in PVOID MappedBase; ...

  7. linux每日命令(1):gzip命令

    gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用. gzip不仅可以用来压缩大的.较少使用的文件以节省磁盘空间,还可以和tar命令一起构成Linux操作系统中比较流 ...

  8. HTML5和CSS3工具资源汇总

    HTML5 & CSS3 准备就绪 该网站通过扇形图表的形式展现了从08年到10年以来各大浏览器对HTML5和CSS3的支持情况.发展势头还是很可观的. HTML5安全手册 CSS3按钮生成器 ...

  9. 如何恢复误删的OneNote页面

    今天不小心把半个月的日记删掉了!(为了减少页面数量,每个月的日记会放在同一个页面上). 幸运的是OneNote有自动备份功能,喜极而泣. 操作方法来自微软支持 打开丢失了最近笔记的笔记本. 单击“文件 ...

  10. 关于mysql的权限的问题

    昨天因为同学的mysql数据库不知道做了什么操作,从而导致root用户无法使用了 具体是使用root用户不需要密码 进去只能看 看到 infomation_schema 表 ,感觉root权限丢失了 ...