线性规划与网络流24题 负载平衡问题


题目描述 Description

    G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最
    少搬运量可以使n 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
    «编程任务:
    对于给定的n 个环形排列的仓库的库存量,编程计算使n 个仓库的库存数量相同的最少
    搬运量。

输入描述 Input Description

    第1 行中有1 个正整数n(n<=100),表示有n
    个仓库。第2 行中有n个正整数,表示n个仓库的库存量。

输出描述 Output Description

    将计算出的最少搬运量输出

样例输入 Sample Input

    5
    17 9 14 16 4

样例输出 Sample Output

    11

建图很简单

先计算出平均值,如果多了就从s向它连一条容量为差值费用为0的边,如果少了就向t连一条容量为差值费用为0的边

然后每个点向旁边两个点连一条容量为inf费用为1的边,然后跑最小费用最大流就行了(一开始傻叉的把一个点拆成了两个点)

 

  1 const

  2     inf=100000;

  3     maxn=105;

  4 type

  5     path=record

  6       next,last,w,c:longint;

  7     end;

  8 var

  9     edge:array[0..maxn*8]of path;

 10     first:array[0..maxn]of longint;

 11     a:array[0..maxn]of longint;

 12     n,tot,s,t:longint;

 13 

 14 procedure insert(x,y,c,w:longint);

 15 begin

 16     inc(tot);

 17     edge[tot].next:=first[x];

 18     edge[tot].last:=y;

 19     edge[tot].w:=w;

 20     edge[tot].c:=c;

 21     first[x]:=tot;

 22     inc(tot);

 23     edge[tot].next:=first[y];

 24     edge[tot].last:=x;

 25     edge[tot].w:=-w;

 26     edge[tot].c:=0;

 27     first[y]:=tot;

 28 end;

 29 

 30 procedure init;

 31 var

 32     i,sum:longint;

 33 begin

 34     read(n);

 35     tot:=1;

 36     s:=0;

 37     t:=n+1;

 38     sum:=0;

 39     for i:=1 to n do

 40       begin

 41         read(a[i]);

 42         inc(sum,a[i]);

 43       end;

 44     sum:=sum div n;

 45     for i:=1 to n do

 46       begin

 47         if a[i]>sum then insert(i,t,a[i]-sum,0);

 48         if a[i]<sum then insert(s,i,sum-a[i],0);

 49       end;

 50     for i:=1 to n do

 51       begin

 52         insert(i,i mod n+1,inf,1);

 53         insert(i mod n+1,i,inf,1);

 54       end;

 55 end;

 56 

 57 var

 58     flow,time,ans:longint;

 59     flag,dis,f:array[0..maxn]of longint;

 60 

 61 function dfs(x,flow:longint):longint;

 62 var

 63     i,d,min:longint;

 64 begin

 65     if x=t then

 66     begin

 67       inc(ans,flow*dis[t]);

 68       exit(flow);

 69     end;

 70     flag[x]:=time;

 71     i:=first[x];

 72     dfs:=0;

 73     while i<>0 do

 74       begin

 75         d:=dis[x]+edge[i].w-dis[edge[i].last];

 76         min:=flow;

 77         if min>edge[i].c then min:=edge[i].c;

 78         if (min>0) and (d<f[edge[i].last]) then f[edge[i].last]:=d;

 79         if (min>0) and (d=0) and (flag[edge[i].last]<>time) then

 80         begin

 81           d:=dfs(edge[i].last,min);

 82           inc(dfs,d);

 83           dec(flow,d);

 84           inc(edge[i xor 1].c,d);

 85           dec(edge[i].c,d);

 86         end;

 87         if flow=0 then break;

 88         i:=edge[i].next;

 89       end;

 90 end;

 91 

 92 procedure work;

 93 var

 94     i,del:longint;

 95 begin

 96     repeat

 97       inc(time);

 98       for i:=1 to t do

 99         f[i]:=inf;

100       inc(flow,dfs(s,inf));

101       del:=inf;

102       for i:=1 to t do

103         if (flag[i]<>time) and (del>f[i]) then del:=f[i];

104       if del=inf then break;

105       for i:=1 to t do

106         if flag[i]<>time then inc(dis[i],del);

107     until false;

108     write(ans);

109 end;

110 

111 begin

112     init;

113     work;

114 end.
View Code

 

你可能感兴趣的:(网络流)