zoukankan      html  css  js  c++  java
  • [CCPC2019秦皇岛] E. Escape

    [CCPC2019秦皇岛E] Escape

    https://codeforces.com/gym/102361/problem/E

    Solution

    观察到性质若干然后建图跑最大流即可。

    我的 ISAP 被卡了,换成 Dinic 却过了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 200005;
    const int inf = 1e+9;
    
    #define reset(x) memset(x,0,sizeof x)
    
    int dis[maxn], ans, cnt = 1, s, t, pre[maxn * 10], nxt[maxn * 10], h[maxn], v[maxn * 10];
    std::queue<int> q;
    void make(int x, int y, int z) {
        pre[++cnt] = y, nxt[cnt] = h[x], h[x] = cnt, v[cnt] = z;
        pre[++cnt] = x, nxt[cnt] = h[y], h[y] = cnt;
    }
    bool bfs() {
        memset(dis, 0, sizeof dis);
        q.push(s), dis[s] = 1;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = h[x]; i; i = nxt[i])
                if (!dis[pre[i]] && v[i])
                    dis[pre[i]] = dis[x] + 1, q.push(pre[i]);
        }
        return dis[t];
    }
    int dfs(int x, int flow) {
        if (x == t || !flow)
            return flow;
        int f = flow;
        for (int i = h[x]; i; i = nxt[i])
            if (v[i] && dis[pre[i]] > dis[x]) {
                int y = dfs(pre[i], min(v[i], f));
                f -= y, v[i] -= y, v[i ^ 1] += y;
                if (!f)
                    return flow;
            }
        if (f == flow)
            dis[x] = -1;
        return flow - f;
    }
    
    int T,n,m,a,b,p[105],e[105];
    char c[105][105];
    
    int calch(int i,int j)
    {
        return 3+((i-1)*m+j-1)*2;
    }
    int calcv(int i,int j)
    {
        return 4+((i-1)*m+j-1)*2;
    }
    int calcx(int i,int j)
    {
        return 3+2*n*m+((i-1)*m+j-1);
    }
    int calcy(int i,int j)
    {
        return 3+3*n*m+((i-1)*m+j-1);
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d",&n,&m,&a,&b);
            reset(dis); reset(pre); reset(nxt); reset(h); reset(v); cnt=1;
            //cout<<calch(n,m)<<" "<<calcv(n,m)<<" "<<calcx(n,m)<<" "<<calcy(n,m)<<endl;
            for(int i=1;i<=n;i++) scanf("%s",c[i]+1);
            for(int i=1;i<=a;i++) scanf("%d",&p[i]);
            for(int i=1;i<=b;i++) scanf("%d",&e[i]);
            for(int i=1;i<=n-1;i++)
                for(int j=1;j<=m;j++)
                    if(c[i][j]=='0' && c[i+1][j]=='0')
                        make(calcv(i,j),calcv(i+1,j),1),
                        make(calcv(i+1,j),calcv(i,j),1);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m-1;j++)
                    if(c[i][j]=='0' && c[i][j+1]=='0')
                        make(calch(i,j),calch(i,j+1),1),
                        make(calch(i,j+1),calch(i,j),1);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(c[i][j]=='0')
                        make(calch(i,j),calcv(i,j),1),
                        make(calcv(i,j),calch(i,j),1);
            for(int i=1;i<=a;i++) if(c[1][p[i]]=='0') make(1,calcv(1,p[i]),1);
            for(int i=1;i<=b;i++) if(c[n][e[i]]=='0') make(calcv(n,e[i]),2,1);
            s=1;t=2;
            ans = 0;
            for (; bfs(); ans += dfs(s, inf));
            if(ans == a) printf("Yes
    ");
            else printf("No
    ");
        }
    }
    
  • 相关阅读:
    2020年12月15日Java学习日记
    2020年12月12日Java学习日记
    2020年12月10日Java学习日记
    2020年12月8日Java学习日记
    2020年12月4日Java学习日记
    2020年12月1日Java学习日记
    2020年11月30日Java学习日记
    2020年11月27日Java学习日记
    2020年11月26日Java学习日记
    B. Navigation System【CF 1320】
  • 原文地址:https://www.cnblogs.com/mollnn/p/11731500.html
Copyright © 2011-2022 走看看