[网络流24题] 负载平衡问题 题解
题目描述
题目描述
公司有 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
输入格式
第一行一个正整数 ,表示有 个仓库。
第二行 个正整数,表示 个仓库的库存量。
输出格式
输出最少搬运量。
题目解析
环形均分纸牌,直接贪心就完了!!!
好吧这是网络流24题,所以我们用网络流做。
首先我们算出每个仓库需要输入和输出的货物数量。
我们建立一个超级源和超级汇。不难发现,如果这个仓库需要输入货物,那么从超级源连一条边到这个点,容量为这个店需要输入的货物的数量,费用为 。如果这个点需要输出货物,那么就从这个点到超级源建一条容量为输出货物数量的边,费用为 。然后在相邻的仓库建费用为 容量无穷大的边。
然后跑一次最小费用最大流就可以了,答案显然是费用。
#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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· 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工具