码迷,mamicode.com
首页 > 其他好文 > 详细

【网络流24题19】负载平衡问题

时间:2018-01-02 23:36:03      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:相同   表示   负载平衡   输入输出   问题   char   输出   link   输入输出格式   

题面戳我
题目描述
\(G\) 公司有 \(n\) 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 \(n\)个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
输入输出格式
输入格式:
文件的第 \(1\) 行中有 \(1\) 个正整数 \(n\),表示有 \(n\) 个仓库。
\(2\) 行中有 \(n\) 个正整数,表示 \(n\) 个仓库的库存量。
输出格式:
输出最少搬运量。
输入输出样例
输入样例#1:

5
17 9 14 16 4

输出样例#1:

11

说明
\(1≤n≤100\)

sol

yyb说这题是傻逼题。yyb果然是坠强的!
不过这题也是真心水。连拆点都不用(好像ppl拆点也跑出来了。。。好吧我们不管他)
源点\(S\)向每个点连容量为原库存,费用为0的边。
每个点向汇点\(T\)连容量为平均库存,费用为0的边。
然后相邻两个点之间连荣量\(inf\)费用1的边。
做完了。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 500;
const int inf = 1e9;
struct edge{int to,next,w,cost;}a[N<<3];
int n,s,t,tot,head[N],cnt=1,dis[N],vis[N],pe[N],ans;
queue<int>Q;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
void link(int u,int v,int w,int cost)
{
    a[++cnt]=(edge){v,head[u],w,cost};
    head[u]=cnt;
    a[++cnt]=(edge){u,head[v],0,-cost};
    head[v]=cnt;
}
bool spfa()
{
    memset(dis,63,sizeof(dis));
    dis[s]=0;Q.push(s);
    while (!Q.empty())
    {
        int u=Q.front();Q.pop();
        for (int e=head[u];e;e=a[e].next)
        {
            int v=a[e].to;
            if (a[e].w&&dis[v]>dis[u]+a[e].cost)
            {
                dis[v]=dis[u]+a[e].cost;pe[v]=e;
                if (!vis[v]) vis[v]=1,Q.push(v);
            }
        }
        vis[u]=0;
    }
    if (dis[t]==dis[0]) return false;
    int sum=inf;
    for (int i=t;i^s;i=a[pe[i]^1].to)
        sum=min(sum,a[pe[i]].w);
    ans+=sum*dis[t];
    for (int i=t;i^s;i=a[pe[i]^1].to)
        a[pe[i]].w-=sum,a[pe[i]^1].w+=sum;
    return true;
}
int main()
{
    n=gi();s=n+1;t=s+1;
    for (int i=1,x;i<=n;i++)
        x=gi(),link(s,i,x,0),tot+=x;
    for (int i=1;i<=n;i++)
        link(i,t,tot/n,0);
    for (int i=1;i<=n;i++)
    {
        int qian=(i^1)?i-1:n;
        int hou=(i^n)?i+1:1;
        link(i,qian,inf,1);
        link(i,hou,inf,1);
    }
    while (spfa());
    printf("%d\n",ans);
    return 0;
}

【网络流24题19】负载平衡问题

标签:相同   表示   负载平衡   输入输出   问题   char   输出   link   输入输出格式   

原文地址:https://www.cnblogs.com/zhoushuyu/p/8178981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!