[网络流24题] 负载平衡问题 题解

负载平衡问题

题目描述

题目描述
G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 n 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
输入格式
第一行一个正整数 n ,表示有 n 个仓库。
第二行 n 个正整数,表示 n 个仓库的库存量。
输出格式
输出最少搬运量。

题目解析

环形均分纸牌,直接贪心就完了!!!
好吧这是网络流24题,所以我们用网络流做。

首先我们算出每个仓库需要输入和输出的货物数量。
我们建立一个超级源和超级汇。不难发现,如果这个仓库需要输入货物,那么从超级源连一条边到这个点,容量为这个店需要输入的货物的数量,费用为 0。如果这个点需要输出货物,那么就从这个点到超级源建一条容量为输出货物数量的边,费用为 0 。然后在相邻的仓库建费用为 1 容量无穷大的边。
然后跑一次最小费用最大流就可以了,答案显然是费用。

#include<queue>
#include<cstdio>
#include<cstring>
#define I inline
#define db double
#define U unsigned
#define R register
#define ll long long
#define RI register int
#define ull unsigned long long
#define abs(x) ((x)>0?(x):(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define Me(a,b) memset(a,b,sizeof(a))
#define EPS (1e-7)
#define INF (0x7fffffff)
#define LL_INF (0x7fffffffffffffff)
#define maxn 139
#define maxm 1039
//#define debug
using namespace std;
#define Type int
I Type read(){
Type sum=0; int flag=0; char c=getchar();
while((c<'0'||c>'9')&&c!='-') c=getchar(); if(c=='-') c=getchar(),flag=1;
while('0'<=c&&c<='9'){ sum=(sum<<1)+(sum<<3)+(c^48); c=getchar(); }
if(flag) return -sum; return sum;
}
int a[maxn],n,ave,sum;
int head[maxn],nex[maxm],to[maxm],c[maxm],w[maxm],kkk=1;//w flow c cost
#define add(x,y,a,b) nex[++kkk]=head[x]; head[x]=kkk; w[kkk]=a; c[kkk]=b; to[kkk]=y;
int flow[maxn],pre[maxn],dis[maxn],vis[maxn],las[maxn],ret,s,t;
queue<int> q,E;
int spfa(){
q=E; q.push(s); Me(dis,0x7f); Me(flow,0x7f); pre[t]=-1; dis[s]=0; RI cur,i;
while(!q.empty()){
cur=q.front(); q.pop(); vis[cur]=0;
for(i=head[cur];i;i=nex[i])
if(w[i]>0&&dis[to[i]]>dis[cur]+c[i]){
dis[to[i]]=dis[cur]+c[i]; las[to[i]]=i; pre[to[i]]=cur;
if(!vis[to[i]]) q.push(to[i]),vis[to[i]]=1; flow[to[i]]=min(flow[cur],w[i]);
}
}
return ~pre[t];
}
void mcmf(){
RI cur;
while(spfa()){
cur=t; ret+=dis[t]*flow[t];
while(cur!=s){ w[las[cur]]-=flow[t]; w[las[cur]^1]+=flow[t]; cur=pre[cur]; }
} return;
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
RI i; n=read(); for(i=0;i<n;i++) a[i]=read(),sum+=a[i];
ave=sum/n; for(i=0;i<n;i++) a[i]-=ave; s=n; t=n+1;
for(i=0;i<n;i++)
if(a[i]>0){ add(s,i,a[i],0) add(i,s,0,0) }
else if(a[i]<0){ add(i,t,-a[i],0) add(t,i,0,0) }
for(i=0;i<n;i++){
add(i,(i+1)%n,INF,1) add((i+1)%n,i,0,-1)
add((i+1)%n,i,INF,1) add(i,(i+1)%n,0,-1)
}
n+=2; mcmf(); printf("%d",ret); return 0;
}
posted @   jiangtaizhe001  阅读(32)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示