zoukankan      html  css  js  c++  java
  • 【网络流24题19】负载平衡问题

    题面戳我
    题目描述
    (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
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    623. Add One Row to Tree 将一行添加到树中
    771. Jewels and Stones 珠宝和石头
    216. Combination Sum III 组合总数三
    384. Shuffle an Array 随机播放一个数组
    382. Linked List Random Node 链接列表随机节点
    向github项目push代码后,Jenkins实现其自动构建
    centos下安装Jenkins
    python提取批量文件内的指定内容
    批处理实现:批量为文件添加注释
    python抓取每期双色球中奖号码,用于分析
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8178981.html
Copyright © 2011-2022 走看看