POJ 3057 Evacuation(二分匹配)
分析:
这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性。
t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d)和p连边,按t从小到大
枚举点增广就好了。无解的情况只有一种,某个人无论如何都无法出去。
- /*********************************************************
- * --Sakura hirahira mai orite ochite-- *
- * author AbyssalFish *
- **********************************************************/
- #include<cstdio>
- #include<iostream>
- #include<string>
- #include<cstring>
- #include<queue>
- #include<vector>
- #include<stack>
- #include<vector>
- #include<map>
- #include<set>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- typedef long long ll;
- const int XY = , MAX_D = , MAX_P = ;//..MAX_T
- char maz[XY][XY+];
- const int maxv = MAX_D*MAX_P, maxe = maxv*MAX_P;
- int hd[maxv],to[maxe],nx[maxe],ec;
- #define eachEage int i = hd[u]; ~i; i = nx[i]
- void add(int u,int v)
- {
- nx[ec] = hd[u];
- to[ec] = v;
- hd[u] = ec++;
- }
- #define PB push_back
- #define resv(x,n) x.reserve(n);
- #define PS push
- vector<int> pX, pY, dX, dY;
- const int dx[] = {,,-,}, dy[] = {,-,,};
- int dist[XY][XY][XY][XY];
- int X,Y;
- void bfs(int x,int y)
- {
- int (* const d)[XY] = dist[x][y];
- memset(d,0xff,sizeof(dist[x][y]));
- queue<int> qx, qy;
- d[x][y] = ;
- qx.PS(x); qy.PS(y);
- while(qx.size()){
- x = qx.front(); qx.pop();
- y = qy.front(); qy.pop();
- for(int k = ; k--;){
- int nx = x+dx[k], ny = y+dy[k];
- if(<=nx && nx<X && <=ny && ny<Y && maz[nx][ny] == '.' && d[nx][ny]<){
- d[nx][ny] = d[x][y]+;
- qx.PS(nx); qy.PS(ny);
- }
- }
- }
- }
- int link[MAX_P];
- int vis[maxv], clk;
- bool aug(int u)
- {
- vis[u] = clk;
- for(eachEage){
- int v = to[i], w = link[v];
- if(w< || (vis[w] != clk && aug(w))){
- link[v] = u;
- return true;
- }
- }
- return false;
- }
- //#define LOCAL
- int main()
- {
- #ifdef LOCAL
- freopen("in.txt","r",stdin);
- #endif
- resv(pX,MAX_P) resv(pX,MAX_P) resv(dX,MAX_D) resv(dY,MAX_D)
- int T; cin>>T;
- while(T--){
- scanf("%d%d",&X,&Y);
- pX.clear(); pY.clear();
- dX.clear(); dY.clear();
- for(int i = ; i < X; i++){
- scanf("%s", maz[i]);
- for(int j = ; j < Y; j++){
- if(maz[i][j] == 'D'){
- dX.PB(i); dY.PB(j);
- }
- else if(maz[i][j] == '.'){
- pX.PB(i); pY.PB(j);
- }
- }
- }
- int d = dX.size(), p = pX.size();
- if(p == ){ puts(""); continue; }
- for(int i = ; i < d; i++){
- bfs(dX[i],dY[i]);
- }
- int n = (X-)*(Y-);
- bool fail = false;
- memset(hd,0xff,sizeof(int)*n*d); ec = ;
- for(int i = ; i < p; i++){
- bool escape = false;
- for(int j = ; j < d; j++){
- if(dist[dX[j]][dY[j]][pX[i]][pY[i]] > ){
- if(!escape) escape = true;
- for(int k = dist[dX[j]][dY[j]][pX[i]][pY[i]]-; k < n; k++){
- add(k*d+j, i);
- }
- }
- }
- if(!escape){
- fail = true; break;
- }
- }
- if(fail){ puts("impossible"); continue; }
- memset(link,-,sizeof(int)*p);
- int cnt = , ans;
- for(int i = ; i < n*d; i++){
- clk++;
- if(aug(i) && ++cnt == p) {
- ans = i/d+;
- }
- }
- printf("%d\n", ans);
- }
- return ;
- }
POJ 3057 Evacuation(二分匹配)的更多相关文章
- POJ 3057 Evacuation (二分匹配)
题意:给定一个图,然后有几个门,每个人要出去,但是每个门每个秒只能出去一个,然后问你最少时间才能全部出去. 析:初一看,应该是像搜索,但是怎么保证每个人出去的时候都不冲突呢,毕竟每个门每次只能出一个人 ...
- TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs
题意:见挑战230页 #include <iostream> #include <cstdio> #include <cstring> #include <c ...
- POJ 3057 Evacuation 二分+最大流
Evacuation 题目连接: http://poj.org/problem?id=3057 Description Fires can be disastrous, especially when ...
- POJ 3057 Evacuation 二分图匹配
每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:10240000 ...
- POJ 3057 Evacuation 题解
题目 Fires can be disastrous, especially when a fire breaks out in a room that is completely filled wi ...
- POJ 3041 - 最大二分匹配
这道题实现起来还是比较简单的,但是理解起来可能有点困难. 我最开始想到的是贪心法,每次消灭当前小行星最多的一行或一列.然而WA了.Discuss区里已经有高人给出反例. 下面给出正确的解法 我们把行和 ...
- POJ 3057 Evacuation(二分图匹配+BFS)
[题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...
- 【最大匹配+二分答案】POJ 3057 Evacuation
题目大意 POJ链接 有一个\(X×Y\)的房间,X代表墙壁,D是门,.代表人.这个房间着火了,人要跑出去,但是每一个时间点只有一个人可以从门出去. 问最后一个人逃出去的最短时间,如果不能逃出去,输出 ...
- poj 2446 Chessboard (二分匹配)
Chessboard Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12800 Accepted: 4000 Descr ...
随机推荐
- Spark RDD(Resilient Distributed Dataset)
基于数据集的处理:从物理存储上加载数据,然后操作数据,然后写入物理存储设备.比如Hadoop的MapReduce. 缺点:1.不适合大量的迭代 2. 交互式查询 3. 不能复用曾经的 ...
- ASP.NET控件之CompareValidator控件
作用:对Textbox或者其他输入框进行比较验证: 属性:ControlToValidate:要验证的控件: ErrorMessage:错误提示信息: ControlToCompare:与此相比的控件 ...
- 洛谷P2294 [HNOI2005]狡猾的商人
P2294 [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要 ...
- 与pocket 对接技术文档
同步每日新增用户接口(kwai 提供) 注释:该接口 每天0点(北京时间)之后 向kwai服务器同步前一天 新增的IMEI号 url:http://m.kwai.com/rest/o/pocket/ ...
- bzoj5506:[gzoi2019]旅行者
传送门 正反两边dijkstra染色,然后枚举一下边,求出最小值就好啦 代码: #include<cstdio> #include<iostream> #include< ...
- vue2格式化时间戳
注意:时间戳分为10位和13位的,10位的是秒,13位的是毫秒 这里给出的是格式化13位的方法,10位的时间戳可以加上3个0 <div id="app">{{time ...
- event对象的使用注意事项
首先event是在事件发生的时候产生的,所以必须在事件发生的事件监听函数里面使用他.不然的话就没用的.会找不到这个事件: 错误的写法: 报错的内容: 正确的写法:
- sourcetree基本使用
非常有用的使用sourcetree开发的步骤文档 https://www.cnblogs.com/fps2tao/p/7825742.html 1) master,最终发布版本,整个项目中有且只有一个 ...
- ubuntu设置nginx为系统服务
ubuntu设置nginx为系统服务,如果没有设置为系统服务,无法执行 sudo service nginx startsudo service nginx stop 设置为系统服务命令 sudo u ...
- ZC01
1.苏州市住房公积金管理中心 http://www.szgjj.gov.cn/szgjj/ 2.苏州社保 http://www.szsbzx.net.cn:9900/web/website/index ...