[网络流24题] 负载平衡

[网络流24题] 负载平衡

 

时间限制:1 s   内存限制:128 MB

 

 

 

 

 

 

 

 

 

 

 

 

 

 

17 9 14 16 4

overload.out

 

 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 }
View Code

 

转载于:https://www.cnblogs.com/hyghb/p/8178190.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值