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;
    }
  • 相关阅读:
    Win7下IE 8内存保护可能导致ActiveX无法安装的问题及其解决方法
    为Windows Server 2000开发和部署ASP.NET 3.5的应用程序
    MOSS 2010:如何为列表设计Infopath表单用于编辑和显示
    Windows Live is designed for you, but maybe not for your browser
    Meet the new WSS SharePoint Foundation 2010
    MOSS 2010: Visual Studio 2010开发体验(3)——调试代码
    MOSS 2010:Visual Studio 2010开发体验(10)——列表开发之内容类型
    MOSS 2010:谁动了我的“共享服务”
    MOSS 2010:通过SharePoint Designer定制列表项的条件格式
    如何访问嵌套母版页中的控件
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8544703.html
Copyright © 2011-2022 走看看