• P2172 [国家集训队]部落战争(最小路径覆盖)


    P2172 [国家集训队]部落战争

    每个点仅走一次:最小路径覆盖

    套路地拆点,具体看代码中的$draw()$

    流量每增加1,意味着一支军队可以多走一格,代价减少1

    最后答案即为总点数$-dinic()$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9') f=f&&(c!='-'),c=getchar();
        while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
        return f?x:-x;
    }
    #define M 400000
    int n,m,R,C,S,T,d[M],cur[M],tt;
    char q[100][100]; bool vis[M];
    int Cnt=1,hd[M],nxt[M],ed[M],poi[M],val[M];
    void adde(int x,int y,int v){
        nxt[ed[x]]=++Cnt; hd[x]=hd[x]?hd[x]:Cnt;
        ed[x]=Cnt; poi[Cnt]=y; val[Cnt]=v;
    }
    void link(int x,int y,int v){adde(x,y,v),adde(y,x,0);}
    #define to poi[i]
    bool Bfs(){
        memset(vis,0,sizeof(vis));
        queue <int> h; h.push(S);
        vis[S]=1; d[S]=0;
        while(!h.empty()){
            int x=h.front(); h.pop();
            for(int i=hd[x];i;i=nxt[i])
                if(!vis[to]&&val[i]>0)
                    vis[to]=1,d[to]=d[x]+1,h.push(to);
        }return vis[T];
    }
    int Dfs(int x,int a){
        if(!a||x==T) return a;
        int F=0,f;
        for(int &i=cur[x];i;i=nxt[i])
            if(d[to]==d[x]+1&&(f=Dfs(to,min(a,val[i])))>0){
                F+=f,a-=f,val[i]-=f,val[i^1]+=f;
                if(!a) break;
            }
        return F;
    }
    int Dinic(){
        int re=0;
        while(Bfs()){
            for(int i=1;i<=T;++i) cur[i]=hd[i];
            re+=Dfs(S,1e9);
        }return re;
    }
    bool is(int x,int y){return x>0&&x<=n&&y>0&&y<=m&&q[x][y]=='.';}
    int id(int x,int y){return x*m-m+y;}
    void draw(int x,int y){
        int p=id(x,y); ++tt; link(S,p,1); link(p+n*m,T,1);
        if(is(x+R,y+C)) link(p,id(x+R,y+C)+n*m,1);
        if(is(x+R,y-C)) link(p,id(x+R,y-C)+n*m,1);
        if(is(x+C,y+R)) link(p,id(x+C,y+R)+n*m,1);
        if(is(x+C,y-R)) link(p,id(x+C,y-R)+n*m,1);
    }
    int main(){
        scanf("%d%d%d%d",&n,&m,&R,&C); S=n*m*2+1; T=S+1;
        for(int i=1;i<=n;++i) scanf("%s",q[i]+1);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                if(q[i][j]=='.') draw(i,j);
        printf("%d
    ",tt-Dinic());
        return 0;
    }
  • 相关阅读:
    iOS中block实现的探究
    [ES6] 19. for ... of
    [ES6] 18. Map
    [ES6] 17. Set
    [ES6] 16. Object Enhancements
    [MEAN Stack] First API -- 5. Using $resource to setup REST app
    [AngularJS] Provider
    [MEAN Stack] First API -- 4. Organize app structure
    [AngularJS] ngCloak
    [Angular-Scaled Web] 9. Control your promises with $q
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/11285613.html
Copyright © 2020-2023  润新知