Luogu P4016 Load Balancing (maximum minimum cost), p4016 Load Balancing
Description
GG has nn warehouses arranged in a circular manner along railway lines. Each Warehouse stores a different amount of goods. How to use a minimum volume of transportation can make the inventory of nn warehouses the same. When carrying goods, it can only be carried between adjacent warehouses.
Input/Output Format
Input Format:
There are 11 positive integers nn in the row 11th of the file, indicating that there are nn warehouses.
There are nn positive integers in the 22nd rows, indicating the inventory of nn warehouses.
Output Format:
Minimum output handling volume.
Input and Output sample input sample #1: Copy
517 9 14 16 4
Output example #1: Copy
11
Description
1 \ leq n \ leq 1001 ≤ n ≤ 100
When the teacher gave a lecture yesterday, he always felt like he had done this question. He seemed to be able to use greedy water. After reading the question, he found that he could indeed use greedy water QWQ ....
Network stream practices
In fact, it is very simple, but I think it is too complicated. QWQ...
From S to each point, the connection capacity is inventory, and the cost is 0.
From each point to the T-linked capacity is the average inventory, the cost is 0 side
The connection capacity between two adjacent points is INF, and the cost is 1 edge
#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\n",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;}