二分 Evacuation
来源:互联网 发布:thinkphp开发cms 编辑:程序博客网 时间:2024/06/18 08:26
题目:点击打开链接
试了各种搜索,觉得一定是搜索姿势不对,一定能搜出来,嗯,一定能·····
先从门反向bfs·····不对,路线要最优·····
那就每个人bfs一遍到每个门的最短时间,再动态规划吧······算了,看书还是·····
总的来说思想就是时间t内某个人能到达某一扇门就建一条边,然后求t对应的最大匹配,自增t,当t为n*m还不能救出所有人认为无解;
由于最大匹配算法可以从一个初始匹配开始运行,所以当我们在求时间为 t s二分图的最大匹配时,可以把 t-1 s时求得的最大匹配作为一个初始匹配。
#include<iostream>#include<algorithm>#include<string>#include<queue>#include<cmath>#include<vector>#include<stdlib.h>#include<iomanip>#include<list>#include<stack>#include<memory.h>#include<ctype.h>using namespace std;typedef long long ll;#define MAX 15 #define INF (1<<30) using namespace std;//#define LOCAL typedef pair<int, int> pii;pii p[MAX*MAX], d[MAX*MAX];vector<int> G[MAX*MAX];const int dir[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } };int dist[MAX][MAX][MAX][MAX], cx[MAX*MAX], cy[2 * MAX*MAX*MAX];int n, m, cp, cd, ans;bool vis[2 * MAX*MAX*MAX];char map[MAX][MAX];void bfs(int x, int y, int dist[MAX][MAX]){int a, b, i;queue<pii> qi;pii tmp;dist[x][y] = 0;qi.push(make_pair(x, y));while (!qi.empty()){tmp = qi.front();qi.pop();for (i = 0; i<4; i++){a = dir[i][0] + tmp.first;b = dir[i][1] + tmp.second;if (a >= 0 && a<n&&b >= 0 && b<m&&map[a][b] == '.'&&dist[a][b] == -1){dist[a][b] = dist[tmp.first][tmp.second] + 1;qi.push(make_pair(a, b));}}}}void add_edge(int a, int b){G[a].push_back(b);}bool dfs(int u){int i, v;for (i = 0; i<G[u].size(); i++){v = G[u][i];if (!vis[v]){vis[v] = true;if (cy[v] == -1 || dfs(cy[v])){cx[u] = v;cy[v] = u;return true;}}}return false;}void Hungary(int k){int i, j;for (i = 0; i<cp; i++){if (cx[i] == -1){//memset(vis,false,sizeof(vis)); for (j = 0; j<cd*k; j++) vis[j] = false;if (dfs(i)) ans++;}}}int main(){int t, i, j, k;scanf("%d", &t);while (t--){scanf("%d %d", &n, &m);for (i = 0; i<n; i++) scanf("%s", map[i]);cp = cd = 0;memset(dist, -1, sizeof(dist));for (i = 0; i<n; i++){for (j = 0; j<m; j++){if (map[i][j] == '.') p[cp++] = make_pair(i, j);else if (map[i][j] == 'D'){d[cd++] = make_pair(i, j);bfs(i, j, dist[i][j]);}}}if (cp == 0){printf("0\n");continue;}ans = 0;memset(cx, -1, sizeof(cx));memset(cy, -1, sizeof(cy));for (k = 1; k<n*m; k++){for (i = 0; i<cp; i++){for (j = 0; j<cd; j++){if (dist[d[j].first][d[j].second][p[i].first][p[i].second] != -1 && dist[d[j].first][d[j].second][p[i].first][p[i].second] <= k)add_edge(i, j + cd*(k - 1));}}Hungary(k);if (ans == cp){printf("%d\n", k);break;}}if (k == n*m) printf("impossible\n");for (i = 0; i<cp; i++) G[i].clear();}}
阅读全文
0 0
- 二分 Evacuation
- POJ3057 Evacuation 【二分匹配】
- poj3057 Evacuation 二分图匹配
- POJ 3057 Evacuation 二分图
- POJ 3057 Evacuation (二分图匹配)
- POJ3057 Evacuation 最大流+二分答案
- poj3057 Evacuation(二分+最大匹配)
- POJ 3057 Evacuation(BFS+二分图匹配)
- poj 3057 Evacuation(二分+二分匹配,好题)
- Poj 3057 Evacuation【二分+Bfs建图+二分匹配】好题
- poj 3057 Evacuation 二分图最大匹配 最短路
- POJ 3057-Evacuation(最短路+二分图匹配)
- POJ 3057:Evacuation (搜索+二分图匹配)
- POJ 3057 Evacuation(一道很好可以加强对二分图理解的题目)
- Evacuation Plan
- Codeforces 78E Evacuation
- hdu 3757 Evacuation Plan
- UVALive 4987 Evacuation Plan
- Vim技巧
- 数组与指针
- Handler机制一点一点带你抛析(1)
- babyos2(3)—— console, kprintf
- hadoop源码解读二
- 二分 Evacuation
- tensorflow 版本查看命令
- 二叉树的某些性质
- JAVA变量初始化的默认值
- 输出一个爱心
- form is not define的原因-JavaScript
- 图像旋转以及C代码实现
- 操作系统常用调度算法
- android ndk cmake c++调用c语言函数