[POJ3057]Evacuation(二分图匹配,BFS,二分,好题)
Posted tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POJ3057]Evacuation(二分图匹配,BFS,二分,好题)相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=3057
题意:《挑战》P230的题。
首先预处理出所有人到所有门的最短距离dis(pxi,pyi,dxj,dyj),然后二分答案。
拿二分出的时间t判断,判断的时候把每一个门拆成t个点,与人连起来,求最大匹配,看匹配结果是否满足与总人数相等。
因为要保证每一个人都在某一个门的一秒出去,所以可以用上述建图方法保证。
RE了不知道在哪里。。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <bitset> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 #include <ctime> 15 #include <set> 16 #include <map> 17 #include <cmath> 18 using namespace std; 19 20 const int maxn = 50500; 21 const int maxm = 33; 22 int nx, ny; 23 int G[maxm][maxn]; 24 int linker[maxn]; 25 bool vis[maxn]; 26 27 bool dfs(int u) { 28 for(int v = 0; v < ny; v++) { 29 if(G[u][v] && !vis[v]) { 30 vis[v] = 1; 31 if(linker[v] == -1 || dfs(linker[v])) { 32 linker[v] = u; 33 return 1; 34 } 35 } 36 } 37 return 0; 38 } 39 40 int hungary() { 41 int ret = 0; 42 memset(linker, -1, sizeof(linker)); 43 for(int u = 0; u < nx; u++) { 44 memset(vis, 0, sizeof(vis)); 45 if(dfs(u)) ret++; 46 } 47 return ret; 48 } 49 50 51 typedef struct Node { 52 int x, y, st; 53 Node() {} 54 Node(int x, int y, int st) : x(x), y(y), st(st) {} 55 }Node; 56 57 const int fx[5] = {0, 0, 1, -1}; 58 const int fy[5] = {1, -1, 0, 0}; 59 int n, m; 60 char mp[maxm][maxm]; 61 int dis[maxm][maxm][maxm][maxm]; 62 vector<int> px, py; 63 vector<int> dx, dy; 64 bool done[maxm][maxm]; 65 66 bool board(int x, int y) { 67 return x >= 0 && x < n && y >= 0 && y < m; 68 } 69 70 void bfs(int sx, int sy) { 71 queue<Node> q; 72 q.push(Node(sx, sy, 0)); 73 memset(done, 0, sizeof(done)); 74 done[sx][sy] = 1; 75 while(!q.empty()) { 76 Node tmp = q.front(); q.pop(); 77 if(mp[tmp.x][tmp.y] == ‘D‘) { 78 dis[sx][sy][tmp.x][tmp.y] = tmp.st; 79 continue; 80 } 81 for(int i = 0; i < 4; i++) { 82 int xx = tmp.x + fx[i]; 83 int yy = tmp.y + fy[i]; 84 if(board(xx, yy) && mp[xx][yy] != ‘X‘ && !done[xx][yy]) { 85 done[xx][yy] = 1; 86 q.push(Node(xx, yy, tmp.st+1)); 87 } 88 } 89 } 90 } 91 92 int id(int t, int i) { 93 return t * dx.size() + i; 94 } 95 96 bool ok(int t) { 97 nx = px.size(); 98 ny = t * dx.size(); 99 memset(G, 0, sizeof(G)); 100 for(int i = 0; i < px.size(); i++) { 101 for(int j = 0; j < dx.size(); j++) { 102 int& d = dis[px[i]][py[i]][dx[j]][dy[j]]; 103 if(d == -1) continue; 104 for(int h = 0; h < t - d; h++) { 105 G[i][id(h, j)] = 1; 106 } 107 } 108 } 109 return hungary() == nx; 110 } 111 112 int main() { 113 // freopen("in", "r", stdin); 114 int T; 115 scanf("%d", &T); 116 while(T--) { 117 scanf("%d%d",&n,&m); 118 memset(mp, 0, sizeof(mp)); 119 memset(dis, -1, sizeof(dis)); 120 px.clear(); py.clear(); 121 dx.clear(); dy.clear(); 122 for(int i = 0; i < n; i++) scanf("%s", mp[i]); 123 for(int i = 0; i < n; i++) { 124 for(int j = 0; j < m; j++) { 125 if(mp[i][j] == ‘.‘) { 126 px.push_back(i); 127 py.push_back(j); 128 } 129 else if(mp[i][j] == ‘D‘) { 130 dx.push_back(i); 131 dy.push_back(j); 132 } 133 } 134 } 135 for(int i = 0; i < px.size(); i++) bfs(px[i], py[i]); 136 int lo = -1, hi = n * m + 1; 137 while(lo <= hi) { 138 int mid = (lo + hi) >> 1; 139 if(ok(mid)) hi = mid - 1; 140 else lo = mid + 1; 141 } 142 if(hi > n * m) puts("impossible"); 143 else printf("%d\n", hi); 144 } 145 return 0; 146 }
以上是关于[POJ3057]Evacuation(二分图匹配,BFS,二分,好题)的主要内容,如果未能解决你的问题,请参考以下文章