题目
注意是
C
C
C种。
大概就这样一个图。
A
C
C
o
d
e
\rm AC\ Code
AC Code
#include<bits/stdc++.h>
#define maxn 10005
#define maxm 40005
#define inf 0x3f3f3f3f
#define Clear(a,b) memset(a,b,sizeof a)
#define Copy(a,b) memcpy(a,b,sizeof a)
using namespace std;
int n,m,N,a[105],id[1005],d[105][105],mark[105][105],tot;
int info[maxn],Prev[maxm],to[maxm],cap[maxm],cnt_e=1;
void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cap[cnt_e]=c; }
void Line(int u,int v,int c){ Node(u,v,c),Node(v,u,0); }
int S,T,h[maxn],buf[maxn],g[maxn];
int aug(int u,int mx){
if(u == T) return mx;
int st = mx , inc;
for(int &i=info[u],v;i;i=Prev[i])
if(cap[i] && h[v=to[i]]+1==h[u]){
inc = aug(v,min(st,cap[i]));
cap[i] -= inc , cap[i^1] += inc;
if((st -= inc) == 0 || h[S]>T) return mx-st;
}
if(!--g[h[u]]) h[S]=T+1;
else ++g[++h[u]];
info[u]=buf[u];
return mx - st;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) scanf("%d",&d[i][j]),mark[i][j] = ++tot;
S=++tot,T=++tot;
for(int i=1;i<=n;i++){
if(!id[a[i]]) Line(id[a[i]]=++tot,T,m*a[i]*a[i]);
Line(mark[i][i],id[a[i]],inf);
}
int stm = 0;
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++){
if(i<j) Line(mark[i][j],mark[i][j-1],inf),Line(mark[i][j],mark[i+1][j],inf);
if(i == j) d[i][j] -= a[i];
if(d[i][j] < 0) Line(mark[i][j],T,-d[i][j]);
else if(d[i][j] > 0) Line(S,mark[i][j],d[i][j]),stm+=d[i][j];
}
Clear(h,0),Clear(g,0),Copy(buf,info);
for(;h[S]<=T;) stm-=aug(S,inf);
printf("%d\n",stm);
}