zoukankan      html  css  js  c++  java
  • POJ 3057 Evacuation(二分匹配)

    分析

    这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性。

    t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d)和p连边,按t从小到大

    枚举点增广就好了。无解的情况只有一种,某个人无论如何都无法出去。

    /*********************************************************
    *      --Sakura hirahira mai orite ochite--              *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    typedef long long ll;
    
    const int XY = 12, MAX_D = 44, MAX_P = 100;//..MAX_T
    char maz[XY][XY+1];
    
    const int maxv = MAX_D*MAX_P, maxe = maxv*MAX_P;
    int hd[maxv],to[maxe],nx[maxe],ec;
    #define eachEage int i = hd[u]; ~i; i = nx[i]
    void add(int u,int v)
    {
        nx[ec] = hd[u];
        to[ec] = v;
        hd[u] = ec++;
    }
    
    #define PB push_back
    #define resv(x,n) x.reserve(n);
    #define PS push
    vector<int> pX, pY, dX, dY;
    
    const int dx[] = {0,0,-1,1}, dy[] = {1,-1,0,0};
    
    int dist[XY][XY][XY][XY];
    int X,Y;
    
    
    void bfs(int x,int y)
    {
        int (* const d)[XY] = dist[x][y];
        memset(d,0xff,sizeof(dist[x][y]));
    
        queue<int> qx, qy;
        d[x][y] = 0;
        qx.PS(x); qy.PS(y);
        while(qx.size()){
            x = qx.front(); qx.pop();
            y = qy.front(); qy.pop();
            for(int k = 4; k--;){
                int nx = x+dx[k], ny = y+dy[k];
                if(0<=nx && nx<X && 0<=ny && ny<Y && maz[nx][ny] == '.' && d[nx][ny]<0){
                    d[nx][ny] = d[x][y]+1;
                    qx.PS(nx); qy.PS(ny);
                }
            }
        }
    }
    
    int link[MAX_P];
    int vis[maxv], clk;
    
    bool aug(int u)
    {
        vis[u] = clk;
        for(eachEage){
            int v = to[i], w = link[v];
            if(w<0 || (vis[w] != clk && aug(w))){
                link[v] = u;
                return true;
            }
        }
        return false;
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        resv(pX,MAX_P) resv(pX,MAX_P) resv(dX,MAX_D) resv(dY,MAX_D)
        int T; cin>>T;
        while(T--){
            scanf("%d%d",&X,&Y);
            pX.clear(); pY.clear();
            dX.clear(); dY.clear();
            for(int i = 0; i < X; i++){
                scanf("%s", maz[i]);
                for(int j = 0; j < Y; j++){
                    if(maz[i][j] == 'D'){
                        dX.PB(i); dY.PB(j);
                    }
                    else if(maz[i][j] == '.'){
                        pX.PB(i); pY.PB(j);
                    }
                }
            }
            int d = dX.size(), p = pX.size();
            if(p == 0){ puts("0"); continue; }
            for(int i = 0; i < d; i++){
                bfs(dX[i],dY[i]);
            }
            int n = (X-2)*(Y-2);
            bool fail = false;
            memset(hd,0xff,sizeof(int)*n*d); ec = 0;
            for(int i = 0; i < p; i++){
                bool escape = false;
                for(int j = 0; j < d; j++){
                    if(dist[dX[j]][dY[j]][pX[i]][pY[i]] > 0){
                        if(!escape) escape = true;
                        for(int k = dist[dX[j]][dY[j]][pX[i]][pY[i]]-1; k < n; k++){
                            add(k*d+j, i);
                        }
                    }
                }
                if(!escape){
                    fail = true; break;
                }
            }
            if(fail){ puts("impossible"); continue; }
            memset(link,-1,sizeof(int)*p);
            int cnt = 0, ans;
            for(int i = 0; i < n*d; i++){
                clk++;
                if(aug(i) && ++cnt == p) {
                    ans = i/d+1;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 4059 [Cerc2012]Non-boring sequences(启发式分治)
    牛客练习赛1 A
    2018年全国多校算法寒假训练营练习比赛(第一场)J
    2018年全国多校算法寒假训练营练习比赛(第一场)C
    2018年全国多校算法寒假训练营练习比赛(第一场)D
    2018年全国多校算法寒假训练营练习比赛(第一场)E
    Wannafly挑战赛7 E
    Wannafly挑战赛7 C
    Wannafly挑战赛7 B
    Wannafly挑战赛7 D
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4947507.html
Copyright © 2011-2022 走看看