• bzoj 4439: [Swerc2015]Landscaping -- 最小割


    4439: [Swerc2015]Landscaping

    Time Limit: 2 Sec  Memory Limit: 512 MB

    Description

    FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示)
    FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示
     
    对于一个4*4的田地,FJ需要走8次。
    收割机是要油的,每次从高地到低地或从低地到高地需要支付A的费用。
    但是FJ有黑科技,可以高地与低地的互变,都只需要一个支付B的费用。
    询问FJ需要支付最小费用。

    Input

    第一行包含四个整数N,M,A,B,意义如上文所述。
    接下来是一个N*M的字符串矩阵,表示农田的地形,’#’表示高地,’.’表示低地。

    Output

    只包含一个正整数,表示最小费用。
    1<=N,M<=50
    1<=A,B<=100000

    Sample Input

    5 4 1000 2000
    ...#
    #..#
    ...#
    ##..
    ###.

    Sample Output

    11000
    样例解释:
    把(2,1)的高地变成低地花费2000,燃料花费9000

    HINT

    我们以源点向高处,低处向汇点连权值为 B 的边,在相邻的点连权值为 A 的边,然后跑最小割

    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    int n,m,S,T;
    inline int pos(int i,int j){return (i-1)*m+j;}
    char str[100];
    int lj[N],to[N],v[N],fro[N],cnt=1;
    void add(int a,int b,int c){fro[++cnt]=lj[a];to[cnt]=b;v[cnt]=c;lj[a]=cnt;}
    void ins(int a,int b,int c){add(a,b,c);add(b,a,0);}
    int q[N],dis[N],l,r;
    bool bfs()
    {
        int x;l=0;r=1;
        memset(dis,0,sizeof(dis));
        dis[S]=1;q[1]=S;
        while(l!=r)
        {
            x=q[l++];if(l==N) l=0;
            for(int i=lj[x];i;i=fro[i])
            {
                if(v[i]&&!dis[to[i]])
                {
                    dis[to[i]]=dis[x]+1;
                    if(to[i]==T) return 1;
                    q[r++]=to[i];if(r==N) r=0;
                }
            }
        }
        return 0;
    }
    int dfs(int x,int p)
    {
        if(x==T) return p;
        int tp,res=0;
        for(int i=lj[x];i;i=fro[i])
        {
            if(v[i]&&dis[to[i]]==dis[x]+1)
            {
                tp=dfs(to[i],min(p-res,v[i]));
                v[i]-=tp;v[i^1]+=tp;
                res+=tp;
                if(res==p) return p;
            }
        }
        if(res==0) dis[x]=0;
        return res;
    }
    int a,b,ans;
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&a,&b);
        S=0;T=n*m+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str+1);
            for(int j=1;j<=m;j++)
            {
                if(str[j]=='#') ins(S,pos(i,j),b);
                else ins(pos(i,j),T,b);
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i>1) ins(pos(i,j),pos(i-1,j),a);
                if(i<n) ins(pos(i,j),pos(i+1,j),a);
                if(j>1) ins(pos(i,j),pos(i,j-1),a);
                if(j<m) ins(pos(i,j),pos(i,j+1),a);
            }
        }
        while(bfs()) ans+=dfs(S,0x3f3f3f3f);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Multidimensional Arrays
    TortoiseGit
    Excel教程(14)
    Excel教程(13)
    Excel教程(12)
    Excel教程(11)
    lock
    reflect
    game
    html x
  • 原文地址:https://www.cnblogs.com/lkhll/p/6901342.html
Copyright © 2020-2023  润新知