zoukankan      html  css  js  c++  java
  • P4016 负载平衡问题

    题目描述

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

    输入输出格式

    输入格式:

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

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

    输出格式:

    输出最少搬运量。

    输入输出出样例

    输入样例#1:
    5
    17 9 14 16 4
    输出样例#1: 
    11

    说明

    1n100

    代码

    网络流24题

    算法:费用流

    建图:很显然我们需要使各仓库的库存量变为平均值,想到费用流保证在平衡的情况下花费最少

    a[i]仓库的库存量与平均值的差。

    于是我们将s向大于平均值的点连边,流量为a[i],费用为0,表示该点应转出a[i]点库存量

    将小于平均值的点向t连边,流量为-a[i],费用为0,表示该点应转入a[i]点库存量

    相邻两点之间连边流量为inf,费用为1

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e6+20,maxm=1e6+50;
    int a[maxn];
    int sum;
    int flow[maxn],dis[maxn],pre[maxn],last[maxn],inq[maxn];
    int head[maxn];
    int s,t;
    struct edge
    {
        int to,next,cap,val;
    }e[maxm];
    int size=1;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    void addedge(int u,int v,int val,int c)
    {
        e[++size].to=v;e[size].cap=val;e[size].val=c;e[size].next=head[u];head[u]=size;
        e[++size].to=u;e[size].cap=0;e[size].val=-c;e[size].next=head[v];head[v]=size;
    }
    void init()
    {
        memset(flow,inf,sizeof(flow));
        memset(dis,inf,sizeof(flow));
        memset(inq,0,sizeof(inq));
        pre[t]=-1;dis[s]=0;
    }
    bool spfa()
    {
        init();
        queue<int>q;
        q.push(s);
        inq[s]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for(int i=head[u];i;i=e[i].next)
            {
                int to=e[i].to;
                if(e[i].cap>0&&dis[to]>dis[u]+e[i].val)
                {
                    dis[to]=dis[u]+e[i].val;
                    flow[to]=min(e[i].cap,flow[u]);
                    pre[to]=u;
                    last[to]=i;
                    if(!inq[to])
                    {
                        q.push(to);
                        inq[to]=1;
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    int mcmf()
    {
        int mc=0;
        while(spfa())
        {
            int u=t;
            mc+=dis[t]*flow[t];
            while(u!=s)
            {
                e[last[u]].cap-=flow[t];
                e[last[u]^1].cap+=flow[t];
                u=pre[u];
            }
        }
        return mc;
    }
    int main()
    {
        int n=read();
        s=0;t=n+1;
        for(int i=1;i<=n;i++)
        a[i]=read(),sum+=a[i];
        sum/=n;
        for(int i=1;i<=n;i++)
        a[i]-=sum;
        for(int i=1;i<=n;i++)
        {
            addedge(i,i-1==0?n:i-1,inf,1);
            addedge(i,i+1==n+1?1:i+1,inf,1);
            if(a[i]>0)addedge(s,i,a[i],0);
            if(a[i]<0)addedge(i,t,-a[i],0);
        }
        printf("%d",mcmf());
        return 0;
    }
    View Code
  • 相关阅读:
    How to build Linux system from kernel to UI layer
    Writing USB driver for Android
    Xposed Framework for Android 8.x Oreo is released (in beta)
    Linux Smartphone Operating Systems You Can Install Today
    Librem 5 Leads New Wave of Open Source Mobile Linux Contenders
    GUADEC: porting GNOME to Android
    Librem 5 – A Security and Privacy Focused Phone
    GNOME and KDE Join Librem 5 Linux Smartphone Party
    Purism计划推出安全开源的Linux Librem 5智能手机
    国产系统之殇:你知道的这些系统都是国外的
  • 原文地址:https://www.cnblogs.com/DriverBen/p/10834665.html
Copyright © 2011-2022 走看看