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);
    }
  • 相关阅读:
    Excel如何关闭进程
    Excel_To_DataTable
    将本地项目上传到Github
    对于session,request,cookie的理解
    static的使用
    Java事件监听的四种实现方式
    静态网页和动态网页
    ps -ef|grep详解
    linux ls -l 详解
    PKU2418_树种统计(map应用||Trie树)
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9830773.html
Copyright © 2011-2022 走看看