每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间。

不断增加时间,然后增广,直到最大匹配。

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cmath>
#include<climits>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define pb(a) push(a)
#define INF 0x1f1f1f1f
#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define PI 3.1415926535898
template<class T> T min(const T& a,const T& b,const T& c)
{
return min(min(a,b),min(a,c));
}
template<class T> T max(const T& a,const T& b,const T& c)
{
return max(max(a,b),max(a,c));
}
void debug()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in","r",stdin);
// freopen("d:\\out1.txt","w",stdout);
#endif
}
int getch()
{
int ch;
while((ch=getchar())!=EOF)
{
if(ch!=' '&&ch!='\n')return ch;
}
return EOF;
} int DX[] = {, , , -};
int DY[] = {, , -, }; const int maxn = ;
char grid[maxn][maxn];
int n, m;
int dist[maxn][maxn][maxn][maxn];
int vis[maxn][maxn];
vector<int> dx,dy,px,py; void bfs(int X,int Y)
{
queue<int> qx,qy;
qx.push(X); qy.push(Y);
memset(vis, , sizeof(vis));
vis[X][Y] = true;
while(!qx.empty())
{
int x = qx.front(); qx.pop();
int y = qy.front(); qy.pop();
for(int d=; d<; d++)
{
int nx = x + DX[d];
int ny = y + DY[d];
if(nx>=&&nx<=n&&ny>=&&ny<=m&&grid[nx][ny]=='.'&&!vis[nx][ny])
{
vis[nx][ny] = true;
dist[X][Y][nx][ny] = dist[X][Y][x][y] + ;
qx.push(nx);
qy.push(ny);
}
}
}
} void prework()
{
memset(dist, -, sizeof(dist));
dx.clear(); dy.clear();
px.clear(); py.clear(); for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
{
if(grid[i][j]=='D')
{
dx.push_back(i);
dy.push_back(j);
dist[i][j][i][j]=;
bfs(i, j);
}else if(grid[i][j]=='.')
{
px.push_back(i);
py.push_back(j);
}
}
//printf("prework: %d %d\n",dx.size(), px.size());
} const int maxv = * + ;
int id[maxn][maxn][];
bool used[maxv];
int match[maxv];
int vcnt;
vector<int> g[maxv];
int ID(int x, int y, int t)
{
int &a = id[x][y][t];
if(a==) a=++vcnt;
return a;
}
void add(int u,int v)
{
g[u].push_back(v);
g[v].push_back(u);
}
void init()
{
for(int i=; i<maxv; i++)
g[i].clear();
memset(id, , sizeof(id));
}
bool dfs(int u)
{
used[u] = true;
for(int i = ; i < g[u].size(); i++)
{
int v = g[u][i];
int w = match[v];
if(w<||!used[w]&&dfs(w))
{
match[u] = v;
match[v] = u;
return true;
}
}
return false;
}
int solve()
{
init();
memset(match, -, sizeof(match));
int res = ;
vcnt = ;
if(px.size() == ) return ;
for(int t=; t<=; t++)
{
for(int i=; i<dx.size(); i++)
{
for(int j=; j<px.size(); j++)
{
int dis = dist[dx[i]][dy[i]][px[j]][py[j]];
if(dis!=- && dis <= t)
{
int u = ID(dx[i], dy[i], t);
int v = ID(px[j], py[j], );
add(u, v);
add(v, u);
}
}
}
for(int i=; i<dx.size(); i++)
{
int u = ID(dx[i], dy[i], t);
memset(used, , sizeof(used));
if(dfs(u))
res++;
}
if(res == px.size()) return t;
}
return -;
}
int main()
{
debug();
int t;
scanf("%d", &t);
for(int ca=; ca<=t; ca++)
{
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++)
scanf("%s", grid[i]+); prework(); int ans = solve();
if(ans != -)
printf("%d\n", ans);
else printf("impossible\n");
}
return ;
}

POJ 3057 Evacuation 二分图匹配的更多相关文章

  1. TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs

    题意:见挑战230页 #include <iostream> #include <cstdio> #include <cstring> #include <c ...

  2. POJ 3057 Evacuation (二分匹配)

    题意:给定一个图,然后有几个门,每个人要出去,但是每个门每个秒只能出去一个,然后问你最少时间才能全部出去. 析:初一看,应该是像搜索,但是怎么保证每个人出去的时候都不冲突呢,毕竟每个门每次只能出一个人 ...

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

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

  4. POJ 3057 Evacuation(二分图匹配+BFS)

    [题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...

  5. POJ 1274 裸二分图匹配

    题意:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶,告诉每头奶牛愿意产奶的牛棚编号,求出最多能分配到的牛栏的数量. 分析:直接二分图匹配: #include<stdio.h> #includ ...

  6. POJ 2446 Chessboard (二分图匹配)

    题意 在一个N*M的矩形里,用1*2的骨牌去覆盖该矩形,每个骨牌只能覆盖相邻的两个格子,问是否能把每个格子都盖住.PS:有K个孔不用覆盖. 思路 容易发现,棋盘上坐标和为奇数的点只会和坐标和为偶数的点 ...

  7. [poj] 3057 Evacuation

    原题 题目大意 墙壁"X",空区域(都是人)".", 门"D". 人向门移动通过时视为逃脱,门每秒能出去一个人,人可以上下左右移动,墙阻止移 ...

  8. POJ 3057 Evacuation(二分匹配)

    分析: 这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性. t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d ...

  9. POJ 3057 Evacuation 二分+最大流

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

随机推荐

  1. Mybatis 新增修改一条SQL

    如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE:如果不会导致唯一值 ...

  2. Android Activity 四种启动模式

    task和back stack(任务和回退栈) 任务启动,task被加入到回退栈的栈顶,返回的时候回退栈的栈顶任务会被弹出,并被销毁,栈中的前一任务恢复运行,当activity销毁是,系统不会保留ac ...

  3. Java日志——2016年5月30日

    1. 局部变量必须初始化,可以定义的同时初始化,也可以定义完成之后进行初始化. 2. Java7新特性:数字之间可以使用"_"连接,eg:23_44_5 = 23445,0B110 ...

  4. 1、Python环境安装部署

    一.环境准备 1.下载Python安装包(至官方网站) https://www.python.org/downloads/ 建议下载安装最新版 2.设置"环境变量" "我 ...

  5. 《CoffeeScript应用开发》学习: 第四章-改进应用程序

    检查值是否存在 使用存在运算符 CoffeeScript中有一个非常有用的存在运算符?,它能正确地处理值是否存在(存在的意思为变量不为undefined或者null)的情况.在变量后添加?来判断它是否 ...

  6. 关于 Dev中的GridControl 中 GridView 的 PopulateColumns() 方法

    最近使用Dev控件,Gridview绑定数据源后不能显示数据,于是在网上查询,说是使用PopulateColumns()方法,可以显示数据.试了一下,管用. 于是在所有更新数据源数据后,都用上了这句话 ...

  7. IIS 中文文件名下载会出现403访问被拒绝

    IIS 中文文件名下载会出现403访问被拒绝 服务器在安全加固后,出现了IIS 中文文件名下载会出现403访问被拒绝 换成英文的就好了

  8. Python 2.7_发送简书关注的专题作者最新一篇文章及连接到邮件_20161218

    最近看简书文章关注了几个专题作者,写的文章都不错,对爬虫和数据分析都写的挺好,因此想到能不能获取最新的文章推送到Ipad网易邮箱大师.邮件发送代码封装成一个函数,从廖雪峰大神那里学的  http:// ...

  9. web测试常用的用例及知识

      1.      Web测试中关于登录的测试... 1 2.      搜索功能测试用例设计... 2 3.      翻页功能测试用例... 3 4.      输入框的测试... 5 5.    ...

  10. 内存工具类:MemoryManager

    个人学习,仅供参考! package com.example.administrator.filemanager.utils;import android.app.ActivityManager;im ...