• [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
    ", hi);
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    C# 使用EWS 读取 Exchange 未读邮件并设置为已读
    .NET 操作 Exchange示例
    Elsa-Core 工作流 使用代码启动审批流或触发审批任务
    Elsa-Core-workflow 从代码启动指定工作流
    .NET CORE 开源工作流 elsa-core 基础使用示例
    文档翻译经验分享(Markdown)
    Orchard Core 开发示例教程
    VMware 与 Hyper-v 并存, 可同时运行 非启动项
    SmtpException: Failure sending mail. ---> System.InvalidOperationException: Asynchronous operations are not allowed in this context.
    Linux (Deppin ,Ubuntu )开发环境配置,VUE & dotnetcore 解决 yarn 找不到问题
  • 原文地址:https://www.cnblogs.com/kirai/p/6776319.html
Copyright © 2020-2023  润新知