zoukankan      html  css  js  c++  java
  • 网络流24题之负载平衡问题

    P4016 负载平衡问题

    题目描述

    G 公司有 n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 n个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。

    输入输出格式

    输入格式:

    文件的第 1 行中有 1 个正整数 n,表示有 n 个仓库。

    2 行中有 n 个正整数,表示 n个仓库的库存量。

     输出格式:

     输出最少搬运量。

    样例输入:

    5
    17 9 14 16 4

    样例输出:

    11

    模拟赛贪心水过,第一道费用流。

    所有仓库的数量都相等,就应该讲多余平均值的仓库运往少于平均值的仓库,多的仓库应该贡献,连向源点;少的仓库应该得到,连向汇点,且费用为0(因为费用指在两个相邻仓库中的运输单价)。

    下一步,每两个相邻的公司也需要连一条+无穷的边权,费用为1.

    之后就没什么了。

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    #define N 50000
    int f[N],cost[N];
    int val[N],to[N],head[N],nex[N];
    int a[N];
    int n;
    int idx=1;
    int S,T;
    int sum;
    int ans,maxflow;
    int nowflow[N];
    int inq[N];
    int pre[N];
    void addedge(int a,int b,int c,int d)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
        cost[idx]=d;
    }
    bool spfa(int S,int T)
    {
        memset(f,0x3f,sizeof(f));
        memset(nowflow,0x3f,sizeof(nowflow));
        memset(inq,0,sizeof(inq));
        queue <int > q;
        f[S]=0;
        inq[S]=1;
        q.push(S);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            inq[x]=0;
            for(int i=head[x];i;i=nex[i])
            {
                if(val[i]&&f[to[i]]>f[x]+cost[i])
                {
                    f[to[i]]=f[x]+cost[i];
                    nowflow[to[i]]=min(nowflow[x],val[i]);
                    pre[to[i]]=i;
                    if(!inq[to[i]])
                    {
                        inq[to[i]]=1;
                        q.push(to[i]);
                    }
                }
            }
        }
        if(f[T]>=0x3f3f3f3f)
            return 0;
        return 1;
    }
    void EK()
    {
        int x=T;
        while(x!=S)
        {
            int i=pre[x];
            val[i]-=nowflow[T];
            val[i^1]+=nowflow[T];
            x=to[i^1];
        }
        maxflow+=nowflow[T];
        ans+=f[T]*nowflow[T];
    }
    int main()
    {
        scanf("%d",&n);
        S=0,T=n+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sum/=n;
        for(int i=1;i<=n;i++)
        {
            if(sum>a[i])
            {
                addedge(S,i,sum-a[i],0);
                addedge(i,S,0,0);
            }
            else
            {
                addedge(i,T,a[i]-sum,0);
                addedge(T,i,0,0);
            }
        }
        for(int i=2;i<=n;i++)
        {
            addedge(i-1,i,1<<30,1);
            addedge(i,i-1,0,-1);
            addedge(i,i-1,1<<30,1);
            addedge(i-1,i,0,-1);
        }
        addedge(n,1,1<<30,1);
        addedge(1,n,0,-1);
        addedge(1,n,1<<30,1);
        addedge(n,1,0,-1);
        while(spfa(S,T))
            EK();
        printf("%d",ans);
    }
  • 相关阅读:
    HDU 2888 Check Corners (模板题)【二维RMQ】
    POJ 3264 Balanced Lineup(模板题)【RMQ】
    poj 3368 Frequent values(经典)【RMQ】
    SPOJ RPLN (模板题)(ST算法)【RMQ】
    UVA 796 Critical Links(模板题)(无向图求桥)
    UVA 315 Network (模板题)(无向图求割点)
    POJ 2029 Get Many Persimmon Trees (模板题)【二维树状数组】
    poj 3067 Japan 【树状数组】
    POJ 2481 Cows 【树状数组】
    POJ 1195 Mobile phones【二维树状数组】
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9830773.html
Copyright © 2011-2022 走看看