转化成供求平衡以后直接连就好了。。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define T 2001
using namespace std;
const int inf=0x7fffffff;
const int N=2005;
int n,m;
int head[N],q[N],dis[N],from[N],a[N];
int cnt=1,sum,ans;
bool vis[N];
struct node
{
int from,to,next,v,c;
}e[100001];
inline void add(int u,int v,int w,int c)
{
cnt++;
e[cnt].from=u;e[cnt].to=v;
e[cnt].v=w;e[cnt].c=c;
e[cnt].next=head[u];head[u]=cnt;
}
inline void ins(int x,int y,int w,int c)
{
add(x,y,w,c);
add(y,x,0,-c);
}
bool spfa()
{
for(int i=0;i<=T;i++)dis[i]=inf;
int t=0,w=1,i,now;
dis[0]=q[0]=0;
vis[0]=1;
while(t!=w)
{
now=q[t];t++;if(t==2001)t=0;
for(int i=head[now];i;i=e[i].next)
{
if(e[i].v&&dis[e[i].to]>dis[now]+e[i].c)
{
from[e[i].to]=i;
dis[e[i].to]=dis[now]+e[i].c;
if(!vis[e[i].to])
{
vis[e[i].to]=1;
q[w++]=e[i].to;
if(w==2001)w=0;
}
}
}
vis[now]=0;
}
if(dis[T]==inf)return 0;return 1;
}
inline void mcf()
{
int i,x=inf;
i=from[T];
while (i)
{
x=min(e[i].v,x);
i=from[e[i].from];
}
i=from[T];
while (i)
{
e[i].v-=x;
e[i^1].v+=x;
ans+=x*e[i].c;
i=from[e[i].from];
}
}
int main()
{
scanf("%d",&n);
fo(i,1,n)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sum/=n;
fo(i,1,n)a[i]-=sum;
fo(i,1,n)
{
if (a[i]>0)ins(0,i,a[i],0);
else ins(i+n,T,-a[i],0);
}
fo(i,1,n)
{
if (i!=1)
{
ins(i,i-1,inf,1);
ins(i,i-1+n,inf,1);
}
if (i!=n)
{
ins(i,i+1,inf,1);
ins(i,i+1+n,inf,1);
}
}
ins(n,1,inf,1);
ins(n,n+1,inf,1);
ins(1,n,inf,1);
ins(1,n+n,inf,1);
while (spfa())mcf();
printf("%d\n",ans);
}