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
  • 相关阅读:
    手贱!使用django,在数据库直接删除了表
    js中在一个函数中引用另一个函数中的函数,可以这么做
    上传下载文件方式
    阻止form提交数据,通过ajax等上传数据
    一种思路,隐藏input标签,通过label关联
    java 寻找水仙花数
    java 统计素数个数问题
    java 兔子生仔问题
    java 实现读取某个目录下指定类型的文件
    通过java 来实现对多个文件的内容合并到一个文件中
  • 原文地址:https://www.cnblogs.com/DriverBen/p/10834665.html
Copyright © 2011-2022 走看看