XJB建建圖就好了,按照差分後的等式建圖,其實完全不用差分自己yy就可以想得到,直接求費用流
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
const int N=1010;
const int inf=0x3f3f3f3f;
int n,m,te,sz,eva,s,t;
int inq[N],d[N],val[N],a[N],head[N],p[N];
struct edge{
int u,v,cap,flow,next,cost;
}e[10010];
queue<int>q;
void add(int u,int v,int cap,int cost)
{
e[++te].u=u;
e[te].v=v;
e[te].cap=cap;
e[te].flow=0;
e[te].cost=cost;
e[te].next=head[u];
head[u]=te;
}
void insert(int u,int v,int cap,int cost){add(u,v,cap,cost);add(v,u,0,-cost);}
int spfa(int &cost,int &flow)
{
memset(d,0x3f,sizeof(d));
memset(a,0,sizeof(a));
q.push(s);d[s]=0;
inq[s]=1;a[s]=inf;
while(!q.empty())
{
int u=q.front();
for (int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if (e[i].cap>e[i].flow&&d[v]>d[u]+e[i].cost)
{
p[v]=i;
a[v]=min(a[u],e[i].cap-e[i].flow);
d[v]=d[u]+e[i].cost;
if (!inq[v])
{
q.push(v);
inq[v]=1;
}
}
}
inq[u]=0;
q.pop();
}
if(!a[t])return 0;
cost+=d[t]*a[t];
flow+=a[t];
for (int u=t;u!=s;u=e[p[u]].u)
{
e[p[u]].flow+=a[t];
e[p[u]^1].flow-=a[t];
}
return 1;
}
int mcmf(int &cost)
{
int flow=0;cost=0;
while(spfa(cost,flow));
return flow;
}
int main()
{
te=1;
cin>>n;
int tot=0;
for (int i=1;i<=n;++i)
scanf("%d",&val[i]),tot+=val[i];
if (tot%n)return 0;
tot/=n,s=n+1,t=s+1;
for (int i=1;i<=n;++i)
{
if (val[i]>tot)insert(s,i,val[i]-tot,0);
else insert(i,t,tot-val[i],0);
if (i!=1)insert(i,i-1,inf,1);
if (i!=n)insert(i,i+1,inf,1);
}
insert(1,n,inf,1),insert(n,1,inf,1);
// for (int i=2;i<=te;i+=2)
// cout<<e[i].u<<' '<<e[i].v<<' '<<e[i].cap<<' '<<e[i].cost<<endl;
int cost;
mcmf(cost);
cout<<cost;
return 0;
}