• UVA 1515 Pool construction 最大流跑最小割


    Pool construction

    You are working for the International Company for Pool Construction, a construction company which
    specializes in building swimming pools. A new client wants to build several new pool areas.
    A pool area is a rectangular grid of w × h square patches, consisting of zero or more (possibly
    disconnected) pools. A pool consists of one or multiple connected hole patches, which will later be
    filled with water. In the beginning, you start with a piece of land where each patch is either a hole in
    the ground (’.’) or flat grass (’#’). In order to transform this land into a pool area, you must adhere
    to the following:
    • You can leave a patch as it is. This costs nothing.
    • If the patch is grass in the beginning, you can dig a hole there. This costs d EUR.
    • If the patch is a hole in the beginning, you can fill the hole and put grass on top. This costs f
    EUR.
    • You must place special boundary elements along each edge running between a final grass patch
    and a final hole patch, to ensure that water does not leak from the pool. This costs b EUR per
    boundary element.
    • The outermost rows and columns of the pool area must always be grass.
    You are given the task of calculating the cost of the cheapest possible pool area given the layout of
    the existing piece of land.
    Input
    On the first line a positive integer: the number of test cases, at most 100. After that per test case:
    • one line with two integers w and h (2 ≤ w, h ≤ 50): the width and height of the building site.
    • one line with three integers d, f and b (1 ≤ d, f, b ≤ 10000): the costs for digging a new hole,
    filling an existing hole, and building a boundary element between a pool and grass patch.
    • h lines of w characters each, denoting the layout of the original building site.
    Output
    Per test case:
    • one line with an integer: the cost of building the cheapest possible pool area from the original
    piece of land.
    Sample Input
    3
    3 3
    5 5 1
    #.#
    #.#
    ###
    5 4
    1 8 1
    #..##
    ##.##
    #.#.#
    #####
    2 2
    27 11 11
    #.
    .#
    Sample Output
    9
    27
    22

    题意:

      给你一个图,

      草地用#号表示,洞用 . 表示.你可以吧草改成洞,这样每格话费d,也可以把洞填上草,话费f.最后还要在草与洞之间修上围栏每边话费b.

      整个图边缘都必须是草.

    题解:

      最小割

      S-草 (边缘的草权值为无穷否则为d,表示吧这条边切断的花费)          

      洞-T (不在边缘的洞与其T相连,权值为f)

      相邻的洞与草之间连双向边, 表示洞变草,草变洞的花费

      跑最大流算法求最小割就好了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include<queue>
    using namespace std;
    const int N = 1e6+20, M = 30005, mod = 1e9+7;
    typedef long long ll;
    //不同为1,相同为0
    
    int n,m,b,F,ans,D,S=0,T=2502;
    char mp[100][100];
    int ss[4][2] = {1,0,0,1};
    int check(int x,int y) {
        if(x<1||y<1||x>n||y>m) return 0;
        return 1;
    }
    namespace NetFlow
    {
        const int MAXN=100000+20,MAXM=1000000,inf=1e9;
        struct Edge
        {
            int v,c,f,nx;
            Edge() {}
            Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
        } E[MAXM];
        int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
        void init(int _n)
        {
            N=_n,sz=0; memset(G,-1,sizeof(G[0])*N);
        }
        void add(int u,int v,int c)
        {
            E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
            E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
            swap(u,v);
             E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
            E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
        }
        int ISAP(int S,int T)
        {//S -> T
            int maxflow=0,aug=inf,flag=false,u,v;
            for (int i=0;i<N;++i)cur[i]=G[i],gap[i]=dis[i]=0;
            for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false)
            {
                for (int &it=cur[u];~it;it=E[it].nx)
                {
                    if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+1)
                    {
                        if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f;
                        pre[v]=u,u=v; flag=true;
                        if (u==T)
                        {
                            for (maxflow+=aug;u!=S;)
                            {
                                E[cur[u=pre[u]]].f+=aug;
                                E[cur[u]^1].f-=aug;
                            }
                            aug=inf;
                        }
                        break;
                    }
                }
                if (flag) continue;
                int mx=N;
                for (int it=G[u];~it;it=E[it].nx)
                {
                    if (E[it].c>E[it].f&&dis[E[it].v]<mx)
                    {
                        mx=dis[E[it].v]; cur[u]=it;
                    }
                }
                if ((--gap[dis[u]])==0) break;
                ++gap[dis[u]=mx+1]; u=pre[u];
            }
            return maxflow;
        }
        bool bfs(int S,int T)
        {
            static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
            dis[S]=0; Q[0]=S;
            for (int h=0,t=1,u,v,it;h<t;++h)
            {
                for (u=Q[h],it=G[u];~it;it=E[it].nx)
                {
                    if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                    {
                        dis[v]=dis[u]+1; Q[t++]=v;
                    }
                }
            }
            return dis[T]!=-1;
        }
        int dfs(int u,int T,int low)
        {
            if (u==T) return low;
            int ret=0,tmp,v;
            for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
            {
                if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
                {
                    if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                    {
                        ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                    }
                }
            }
            if (!ret) dis[u]=-1; return ret;
        }
        int dinic(int S,int T)
        {
            int maxflow=0,tmp;
            while (bfs(S,T))
            {
                memcpy(cur,G,sizeof(G[0])*N);
                while (tmp=dfs(S,T,inf)) maxflow+=tmp;
            }
            return maxflow;
        }
    }
    using namespace NetFlow;
    
    void Links() {
         for(int i=1;i<=m;i++)
            add(S,i,inf);
        for(int i=1;i<=m;i++)
            add(S,(n-1)*m+i,inf);
        for(int i=2;i<n;i++)
            add(S,(i-1)*m+1,inf);
        for(int i=2;i<n;i++)
            add(S,i*m,inf);
        for(int i=2;i<n;i++) {
            for(int j=2;j<m;j++) {
                if(mp[i][j]=='#') add(S,(i-1)*m+j,D);
                else add((i-1)*m+j,T,F);
            }
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                for(int k=0;k<2;k++) {
                    int xx = i+ss[k][0];
                    int yy = j+ss[k][1];
                    if(check(xx,yy)) {
                         add((i-1)*m+j,(xx-1)*m+yy,b);
                    }
                }
            }
        }
        ans+=dinic(S,T);
    }
    int main () {
        int GG = 0;
        scanf("%d",&GG);
        while(GG--) {
            ans = 0;
            scanf("%d%d%d%d%d",&m,&n,&D,&F,&b);
            for(int i=1;i<=n;i++){
                 getchar();
                 for(int j=1;j<=m;j++) scanf("%c",&mp[i][j]);
            }
            for(int i=1;i<=m;i++)
                if(mp[1][i]=='.') ans+=F,mp[1][i] = '#';
            for(int i=1;i<=m;i++)
                if(mp[n][i]=='.') ans+=F,mp[n][i] = '#';
            for(int i=1;i<=n;i++)
                if(mp[i][1]=='.') ans+=F,mp[i][1] = '#';
            for(int i=1;i<=n;i++)
                if(mp[i][m]=='.') ans+=F,mp[i][m] = '#';
            init(8000);
           // cout<<ans<<endl;
            Links();
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    内存池(MemPool)技术详解
    关于项目时间管理的六点须知
    如何与你的老大沟通?
    一个简单的面试题
    Windows下的Memcache安装与测试教程
    反向代理服务器的工作原理
    Linux下的Memcache安装方法
    TCP/IP协议详解
    浅谈负载均衡技术与分类
    MySQL数据备份和恢复的方法大全
  • 原文地址:https://www.cnblogs.com/zxhl/p/5304308.html
Copyright © 2020-2023  润新知