POJ 3057 网络流 Evacuation
题意:
有一个n×m的房间,四周每个格子要么是墙要么是门。中间部分是墙或者人。
现在所有人要从房间逃出去,每个人的速度为1,也就是每个单位时间只能向上下左右四个方向走一格。
多个人可以站在同一个格子上,但是每个时刻每个门只能通过一格人,求所有人从房间中逃出去所需要的最少时间。
分析:
把每个人看成一个点,然后把每个时刻和门组成的二元组看成一个点。
如果两点之间连一条边表示这个人在这个时刻从这个门逃出去。
所以我们可以从小到大将时间逐渐加1,直到找到最大匹配为止。
在增加点的时候,可以在之前最大流基础上增广,这样更快。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define MP make_pair
using namespace std; typedef pair<int, int> PII; const int INF = 0x3f3f3f3f;
const int maxh = ;
const int maxnode = ; char maze[maxh][maxh];
int id[maxh][maxh]; int row, col; vector<PII> people, doors; int dx[] = { , , -, };
int dy[] = { , , , - }; int dist[][]; //the distance from every door to people
int steps[maxh][maxh]; bool inline in(int x, int y) { return x >= && x < row && y >= && y < col; } bool vis[maxh][maxh]; void bfs(PII s)
{
int st = id[s.first][s.second];
steps[s.first][s.second] = ;
queue<PII> Q;
Q.push(s);
memset(vis, false, sizeof(vis));
vis[s.first][s.second] = true; while(!Q.empty())
{
PII t = Q.front(); Q.pop();
for(int i = ; i < ; i++)
{
int x = t.first + dx[i];
int y = t.second + dy[i];
if(in(x, y) && !vis[x][y] && maze[x][y] == '.')
{
vis[x][y] = true;
dist[st][id[x][y]] = steps[x][y] = steps[t.first][t.second] + ;
Q.push(MP(x, y));
}
}
}
} struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
}; int nodes;
vector<int> G[maxnode];
vector<Edge> edges; void init()
{
edges.clear();
for(int i = ; i < nodes; i++) G[i].clear();
} void AddEdge(int u, int v, int cap)
{
edges.push_back(Edge(u, v, cap, ));
edges.push_back(Edge(v, u, , ));
int m = edges.size();
G[u].push_back(m - );
G[v].push_back(m - );
} int s, t;
bool visit[maxnode];
int d[maxnode], cur[maxnode]; bool BFS()
{
memset(visit, false, sizeof(visit));
queue<int> Q;
Q.push(s);
d[s] = ;
visit[s] = true; while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = ; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
int v = e.to;
if(!visit[v] && e.cap > e.flow)
{
visit[v] = true;
Q.push(v);
d[v] = d[u] + ;
}
}
} return visit[t];
} int DFS(int u, int a)
{
if(u == t || a == ) return a;
int flow = , f;
for(int& i = cur[u]; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
int v = e.to;
if(d[v] == d[u] + && (f = DFS(v, min(a, e.cap - e.flow))) > )
{
e.flow += f;
edges[G[u][i]^].flow -= f;
flow += f;
a -= f;
if(a == ) break;
}
}
return flow;
} int Maxflow()
{
int flow = ;
while(BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
return flow;
} void Readuce()
{
for(int i = ; i < edges.size(); i++)
edges[i].cap -= edges[i].flow, edges[i].flow = ;
} int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d%d", &row, &col);
for(int i = ; i < row; i++) scanf("%s", maze[i]); memset(id, , sizeof(id));
people.clear(); doors.clear();
int psz = , dsz = ;
for(int i = ; i < row; i++)
for(int j = ; j < col; j++)
{
if(maze[i][j] == 'D') { doors.push_back(MP(i, j)); id[i][j] = dsz++; }
else if(maze[i][j] == '.') { people.push_back(MP(i, j)); id[i][j] = psz++; }
} memset(dist, 0x3f, sizeof(dist));
for(int i = ; i < dsz; i++) bfs(doors[i]);
bool unreachable = false;
for(int i = ; i < psz; i++)
{
bool reach = false;
for(int j = ; j < dsz; j++)
if(dist[j][i] < INF) { reach = true; break; }
if(reach == false) { unreachable = true; break; }
} if(unreachable) { puts("impossible"); continue; } int tot_time = ;
s = , t = ;
nodes = + psz;
init();
for(int i = ; i < psz; i++) AddEdge(s, i + , ); int matches = ;
for(;;)
{
tot_time++;
for(int i = ; i < dsz; i++)
{
G[nodes].clear();
AddEdge(nodes, t, );
for(int j = ; j < psz; j++)
if(dist[i][j] <= tot_time) AddEdge(j + , nodes, );
nodes++;
}
matches += Maxflow();
if(matches == psz) break;
Readuce();
}
printf("%d\n", tot_time);
} return ;
}
代码君
POJ 3057 网络流 Evacuation的更多相关文章
- POJ 3057 Evacuation 二分+最大流
Evacuation 题目连接: http://poj.org/problem?id=3057 Description Fires can be disastrous, especially when ...
- POJ 3057 Evacuation(二分图匹配+BFS)
[题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...
- [poj] 3057 Evacuation
原题 题目大意 墙壁"X",空区域(都是人)".", 门"D". 人向门移动通过时视为逃脱,门每秒能出去一个人,人可以上下左右移动,墙阻止移 ...
- POJ 3057 Evacuation 题解
题目 Fires can be disastrous, especially when a fire breaks out in a room that is completely filled wi ...
- 【最大匹配+二分答案】POJ 3057 Evacuation
题目大意 POJ链接 有一个\(X×Y\)的房间,X代表墙壁,D是门,.代表人.这个房间着火了,人要跑出去,但是每一个时间点只有一个人可以从门出去. 问最后一个人逃出去的最短时间,如果不能逃出去,输出 ...
- POJ 3057 Evacuation 二分图匹配
每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:10240000 ...
- POJ 3057 Evacuation (二分匹配)
题意:给定一个图,然后有几个门,每个人要出去,但是每个门每个秒只能出去一个,然后问你最少时间才能全部出去. 析:初一看,应该是像搜索,但是怎么保证每个人出去的时候都不冲突呢,毕竟每个门每次只能出一个人 ...
- POJ 3057 Evacuation(二分匹配)
分析: 这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性. t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d ...
- TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs
题意:见挑战230页 #include <iostream> #include <cstdio> #include <cstring> #include <c ...
随机推荐
- 将SpringBoot默认使用的tomcat替换为undertow
随着微服务的兴起,越来越多的互联网应用在选择web容器时使用更加轻量的undertow或者jetty.SpringBoot默认使用的容器是tomcat,如果想换成undertow容器,只需修改pom. ...
- UIScrollView使用stoboard自动布局
使用stoboard布局 scrollView 是有点麻烦的,首先我们往往约束好一个 scrollView 然后在添加子控件,此时都会报错,原因是, scrollView必须确定滚动范围 然后在使用V ...
- VirtualBox中出现UUID have already exists ,并且数字键盘numlock效果相反
原文地址:https://www.cnblogs.com/xqzt/p/5053338.html 原因:由于linux密码登录错误,修改也报错误,所以只能重新安装虚拟机并在其中安装镜像文件,但是安装镜 ...
- npm使用快速的安装源(nrm)
安装 npm install nrm --global 使用 nrm ls 切换安装源 nrm use taobao 测速 nrm test npm 参考地址:http://codingdict.co ...
- Vue.js + Webpack + ECMAScript 6 入门教程
Vue.js学习教程 1.Vue.js——60分钟快速入门 2.Vue.js——60分钟组件快速入门(上篇) 3.Vue.js——60分钟组件快速入门(下篇) 4.Vue.js——基于$.ajax实现 ...
- 深入理解Java流机制(一)
一.前言 C语言本身没有输入输出语句,而是调用"stdio.h"库中的输入输出函数来实现.同样,C++语言本身也没有输入输出,不过有别于C语言,C++有一个面向对象的I/O流类库& ...
- Python+selenium之疑难点解决之去除readonly的限制
去除文本框的readonly只读模式的限制 如图所示:去除卡号readonly限制 代码如图所示: js = 'document.getElementById("cardNo"). ...
- C#中Image类与byte[]之间的转换
//将image转化为二进制 public byte[] GetByteImage(Image img) { byte[] bt = null; if (!img.Equals(null)) { us ...
- 一点对原生HTTP请求的理解与总结
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10946165.html,多谢,=.=~ 术语 HTTP:超文本传输协议,规定Web浏览器如何从W ...
- JavaScript_6_函数
函数是由事件驱动的或者当它被调用执行的可重复使用的代码块 调用带参数的函数 带有返回值的函数 <!DOCTYPE html> <html> <head> <t ...