zoukankan      html  css  js  c++  java
  • 洛谷P4016 负载平衡问题(最小费用最大流)

    题目描述

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

    输入输出格式

    输入格式:

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

    第 22 行中有 nn 个正整数,表示 nn 个仓库的库存量。

    输出格式:

    输出最少搬运量。

    输入输出样例

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

    说明

    1 leq n leq 1001n100

     

    昨天老师讲课的时候总在冥冥之中感觉这题貌似做过,貌似可以用贪心水过去,看了题解发现的确可以用贪心水QWQ....

    网络流做法

    其实很简单,只是我太菜想的太复杂了QWQ...

    从S向每个点连容量为库存量,费用为0的边

    从每个点向T连容量为平均库存量,费用为0的边

    在相邻两个点之间连容量为INF,费用为1的边

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define AddEdge(x,y,z,f) add_edge(x,y,z,f),add_edge(y,x,-z,0)
    using namespace std;
    const int INF=1e8+10;
    const int MAXN=1e4+10;
    int N,M,S,T;
    int C[MAXN][MAXN];
    struct node
    {
        int u,v,w,f,nxt;
    }edge[MAXN];
    int head[MAXN],num=2;
    inline void add_edge(int x,int y,int z,int f)
    {
        edge[num].u=x;
        edge[num].v=y;
        edge[num].w=z;
        edge[num].f=f;
        edge[num].nxt=head[x];
        head[x]=num++;
    }
    int dis[MAXN],vis[MAXN],Pre[MAXN];
    bool SPFA()
    {
        memset(dis,0xf,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int>q;
        q.push(S);
        dis[S]=0;
        while(q.size()!=0)
        {
            int p=q.front();q.pop();
            vis[p]=0;
            for(int i=head[p];i!=-1;i=edge[i].nxt)
            {
                if(edge[i].f&&dis[edge[i].v]>dis[p]+edge[i].w)
                {
                    dis[edge[i].v]=dis[p]+edge[i].w;
                    Pre[edge[i].v]=i;
                    if(!vis[edge[i].v])
                        vis[edge[i].v]=1,q.push(edge[i].v);
                }
            }
        }
        return dis[T]<INF;
    }
    int F()
    {
        int nowflow=INF;
        for(int now=T;now!=S;now=edge[Pre[now]].u)
            nowflow=min(nowflow,edge[Pre[now]].f);
        for(int now=T;now!=S;now=edge[Pre[now]].u)
            edge[Pre[now]].f-=nowflow,
            edge[Pre[now]^1].f+=nowflow;
        return nowflow*dis[T];
    }
    void MCMF()
    {
        int ans=0;
        while(SPFA())
            ans+=F();
        printf("%d
    ",abs(ans));
    }
    int pre(int i)
    {
        if(i!=1) return i-1;
        else return N;
    }
    int nxt(int i)
    {
        if(i!=N) return i+1;
        else return 1;
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #endif
        memset(head,-1,sizeof(head));
        scanf("%d",&N);
        int tot=0;
        S=0,T=N+1;
        for(int i=1;i<=N;i++)
        {
            int x;scanf("%d",&x);
            AddEdge(S,i,0,x);
            tot+=x;
        }
        tot=tot/N;
        for(int i=1;i<=N;i++)
            AddEdge(i,T,0,tot);
        for(int i=1;i<=N;i++)
        {
            AddEdge(i,pre(i),1,INF);
            AddEdge(i,nxt(i),1,INF);
        }
        MCMF();
        return 0;
    }
  • 相关阅读:
    改造vant日期选择
    css3元素垂直居中
    npm综合
    (转)网页加水印方法
    Mac下IDEA自带MAVEN插件的全局环境配置
    隐藏注册控件窗口
    High performance optimization and acceleration for randomWalk, deepwalk, node2vec (Python)
    How to add conda env into jupyter notebook installed by pip
    The Power of WordNet and How to Use It in Python
    背单词app测评,2018年
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8544703.html
Copyright © 2011-2022 走看看