POJ 3057 Evacuation(一道很好可以加强对二分图理解的题目)
来源:互联网 发布:win10 无网络访问权限 编辑:程序博客网 时间:2024/06/04 19:29
这是挑战上面的一道题。
一开始我按照自己思路,先跑一遍bfs,得到每个人到门的距离,然后每分钟都建立一次二分图,跑一遍二分图,用总人数减去跑出来得到的结果,直到0才停止。
但是,这样的做法是错误的。我自己拿了网上别人AC的代码然后自己造数据发现,下面这一组数据我跑出来的有问题
6 6
XDXXXX
D....D
X.X..X
X.XX.X
X...XX
XXXDXX
答案应该是4但是我的却是5,原因在于在第二秒的时候第二行第三个点被第二行最右边的D匹配掉了,后面无法更正这个结果,导致了第二行右边的D接管了靠近他的五个点。
所以正确的做法依然是,一个门在每个时间点都建立,然后左边是人,右边是门来跑二分图,这样他才会更正上面不是最优的结果。
参考了挑战上面的解法。
代码如下:
#include<iostream>#include<cstdio>#include<vector>#include<queue>#include<utility>#include<stack>#include<algorithm>#include<cstring>#include<string>using namespace std;typedef pair<int, int> pii;const int maxn = 1005;int n, m;int p_x[maxn], p_y[maxn], d_x[maxn], d_y[maxn], p, d;char graph[maxn][maxn];bool vst[15][15];int dis[15][15][15][15], dir[][2] = {0, 1, 0, -1, 1, 0, -1, 0};int uN, vN; //u,v数目vector <int> G[maxn];int linker[4805];bool used[4805];bool dfs(int u){ for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(!used[v]) { used[v] = true; if(linker[v] == -1 || dfs(linker[v])) { linker[v] = u; return true; } } } return false; } int hungary(){ int res = 0; int u; memset(linker, -1, sizeof(linker)); for(u = 0; u < uN; u++) { memset(used, 0, sizeof(used)); if(dfs(u)) res++; } return res; } int solve() {uN = p;vN = 0;for(int t = 1; t < 105; t++) {vN = t * d;for(int i = 0; i < p; i++) {for(int j = 0; j < d; j++) {int tmp = dis[ p_x[i] ][ p_y[i] ][ d_x[j] ][ d_y[j] ];if(tmp != -1 && tmp <= t) {G[i].push_back((t - 1) * d + j);}}}int res = hungary();if(res == p)return t;}return -1;}struct node{int x, y, step;node(){}node(int a, int b, int c) {x = a;y = b;step = c;}};inline bool Check(int x, int y) {if(x >= 0 && x < n && y >= 0 && y < m && !vst[x][y] && graph[x][y] == '.')return 1;return 0;}inline void bfs(int sx, int sy) {node now, next;memset(vst, 0, sizeof(vst));queue <node> q;q.push(node(sx, sy, 0));vst[sx][sy] = 1;while(!q.empty()) {now = q.front();q.pop();next.step = now.step + 1;for(int i = 0; i < 4; i++) {next.x = now.x + dir[i][0];next.y = now.y + dir[i][1];if(Check(next.x, next.y)) {q.push(next);vst[next.x][next.y] = 1;dis[next.x][next.y][sx][sy] = next.step;}}}}int main() {#ifndef ONLINE_JUDGEfreopen("poj_in.txt", "r", stdin);// freopen("poj_out.txt", "w", stdout);#endifint T;cin >> T;while(T--) {cin >> n >> m;p = d = 0;memset(dis, -1, sizeof(dis));for(int i = 0; i < maxn; i++)G[i].clear();for(int i = 0; i < n; i++) scanf("%s", &graph[i]);for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {if(graph[i][j] == 'D') {d_x[d] = i;d_y[d++] = j;bfs(i, j);} else if(graph[i][j] == '.') {p_x[p] = i;p_y[p++] = j;}}}int ans = solve();if(ans != -1)printf("%d\n", ans);elseprintf("impossible\n");}return 0;}
阅读全文
0 0
- POJ 3057 Evacuation(一道很好可以加强对二分图理解的题目)
- POJ 3057 Evacuation 二分图
- POJ 3057-Evacuation(最短路+二分图匹配)
- POJ 3057:Evacuation (搜索+二分图匹配)
- POJ 3057 Evacuation (二分图匹配)
- POJ 3057 Evacuation(BFS+二分图匹配)
- poj 3057 Evacuation 二分图最大匹配 最短路
- poj 3414 Pots(认为是一道很好的bfs题目)
- poj 3057 Evacuation(二分+二分匹配,好题)
- Poj 3057 Evacuation【二分+Bfs建图+二分匹配】好题
- 很好的一道思维题目(有坑点的)
- stl-map的一道很好的题目
- 对卿学姐的一道题目的自己的理解
- POJ 3057 Evacuation (最大流加边)
- poj 3057 Evacuation
- POJ 3057 Evacuation 笔记
- POJ 3057 Evacuation
- poj3057 Evacuation 二分图匹配
- 解决R绘图时报错X11
- JAVA集群分布式框架几个主要技术
- 强连通分量 Tarjan算法
- JS产生随机数
- H5面试---怎么解决 display:inline-block 之间显示间隙问题
- POJ 3057 Evacuation(一道很好可以加强对二分图理解的题目)
- 梯度下降法的理解
- JDateTime简介与使用
- H5面试----CSS 选择符有哪些
- window.history方法
- BZOJ 1803: Spoj1487 Query on a tree III 主席树题解
- 分布式服务框架 Zookeeper -- 管理分布式环境中的数据
- 图像处理之常用插值算法
- HDU 5178 pairs