[网络流24题] 负载平衡
时间限制:1 s 内存限制:128 MB
17 9 14 16 4
overload.out
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=115; 4 const int maxm=maxn*maxn*2; 5 const int inf=0x3fffffff; 6 int n,a[maxn],ave,b[maxn]; 7 int s,t,tot=-1,fi[maxn],next[maxm],to[maxm],cost[maxm],flow[maxm]; 8 int ans,que[maxn],head,tail,cur[maxn],vis[maxn],dis[maxn]; 9 void edge_add(int x,int y,int f,int c){ 10 to[++tot]=y;next[tot]=fi[x];fi[x]=tot;cost[tot]=c;flow[tot]=f; 11 to[++tot]=x;next[tot]=fi[y];fi[y]=tot;cost[tot]=-c;flow[tot]=0; 12 } 13 bool bfs(){ 14 head=tail=1; 15 for(int i=s;i<=t;i++)cur[i]=fi[i],dis[i]=inf,vis[i]=0; 16 que[++tail]=s;vis[s]=1;dis[s]=0; 17 while(head!=tail){ 18 head++; 19 if(head==110)head=1; 20 int u=que[head]; 21 vis[u]=0; 22 for(int i=fi[u];i+1;i=next[i]){ 23 if(flow[i]&&dis[to[i]]>dis[u]+cost[i]){ 24 dis[to[i]]=dis[u]+cost[i]; 25 if(!vis[to[i]]){ 26 vis[to[i]]=1; 27 tail++; 28 if(tail==110)tail=1; 29 que[tail]=to[i]; 30 } 31 } 32 } 33 } 34 return dis[t]!=inf; 35 } 36 int dfs(int x,int f){ 37 vis[x]=1; 38 if(x==t)return f; 39 for(int i=cur[x];i+1;i=next[i]){ 40 cur[x]=i; 41 if(!vis[to[i]]&&flow[i]&&dis[to[i]]==dis[x]+cost[i]){ 42 int g=dfs(to[i],min(f,flow[i])); 43 if(g){ 44 ans+=g*cost[i]; 45 flow[i]-=g; 46 flow[i^1]+=g; 47 return g; 48 } 49 } 50 } 51 return 0; 52 } 53 void dinic(){ 54 while(bfs()) 55 while(dfs(s,inf)); 56 printf("%d\n",ans); 57 } 58 int main() 59 { 60 scanf("%d",&n); 61 s=0;t=n+1; 62 memset(fi,-1,sizeof(fi)); 63 for(int i=1;i<=n;i++)scanf("%d",&a[i]),ave+=a[i]; 64 ave/=n; 65 for(int i=1;i<=n;i++)b[i]=a[i]-ave; 66 for(int i=1;i<=n;i++){ 67 for(int j=i+1;j<=n;j++){ 68 if(b[i]*b[j]>=0)continue; 69 if(b[i]>0)edge_add(i,j,inf,min(j-i,i+n-j)); 70 else edge_add(j,i,inf,min(j-i,i+n-j)); 71 } 72 } 73 for(int i=1;i<=n;i++){ 74 if(b[i]>0)edge_add(s,i,b[i],0); 75 if(b[i]<0)edge_add(i,t,-b[i],0); 76 } 77 dinic(); 78 return 0; 79 }