这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=200007,inf=0x7fffffff;
typedef long long LL;
using namespace std;
int n,m,s,t,num,D[107][107],id[107][107],ans;
map<int,int>mp;
template<typename T> void read(T &x) {
T f=1; x=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct edge {
int u,v,fl,cap,nx;
edge(){}
edge(int u,int v,int fl,int cap,int nx):u(u),v(v),fl(fl),cap(cap),nx(nx){}
}e[N];
int fir[N],cur[N],ecnt=1,p[N];
void add(int u,int v,int cap) {
e[++ecnt]=edge(u,v,0,cap,fir[u]); fir[u]=ecnt;
e[++ecnt]=edge(v,u,0,0,fir[v]); fir[v]=ecnt;
}
int calc(int s,int t) {
int fl=inf;
for(int i=t;i!=s;i=e[p[i]].u)
fl=min(fl,e[p[i]].cap-e[p[i]].fl);
for(int i=t;i!=s;i=e[p[i]].u)
e[p[i]].fl+=fl,e[p[i]^1].fl-=fl;
return fl;
}
int d[N],c[N];
queue<int>que;
void bfs(int s,int t) {
for(int i=1;i<=n;i++) cur[i]=fir[i],d[i]=n,c[i]=0;
que.push(t); d[t]=0;
while(!que.empty()) {
int x=que.front();
que.pop();
for(int i=fir[x];i;i=e[i].nx) if(e[i].cap==0) {
int y=e[i].v;
if(d[y]==n) {
d[y]=d[x]+1;
que.push(y);
}
}
}
}
int ISAP(int s,int t) {
int res=0;
bfs(s,t);
for(int i=1;i<=n;i++) c[d[i]]++;
for(int x=s;d[x]<n;) {
if(x==t) {
res+=calc(s,t);
x=s;
}
int ok=0;
for(int &i=cur[x];i;i=e[i].nx)
if(e[i].fl<e[i].cap&&d[e[i].v]+1==d[x]) {
p[x=e[i].v]=i; ok=1; break;
}
if(!ok) {
int M=n; cur[x]=fir[x];
for(int i=fir[x];i;i=e[i].nx) if(e[i].cap>e[i].fl) {
M=min(M,d[e[i].v]+1);
}
if(!(--c[d[x]])) break;
c[d[x]=M]++;
if(x!=s) x=e[p[x]].u;
}
}
return res;
}
int main() {
read(n); read(m);
s=++num; t=++num; num+=n;
For(i,1,n) {
int col; read(col);
if(!mp[col]) {
mp[col]=++num;
add(num,t,m*col*col);
}
add(i+2,mp[col],inf);
add(i+2,t,col);
}
For(i,1,n)
For(j,i,n) {
read(D[i][j]); id[i][j]=++num;
if(D[i][j]>=0) {
add(s,num,D[i][j]);
ans+=D[i][j];
}
else add(num,t,-D[i][j]);
add(num,i+2,inf);
add(num,j+2,inf);
}
For(i,1,n)
For(j,i,n) if(i!=j) {
add(id[i][j],id[i+1][j],inf);
add(id[i][j],id[i][j-1],inf);
}
n=num;
ans-=ISAP(s,t);
printf("%d
",ans);
return 0;
}