基本上对着第一篇题解写的,但是 T 了 #2 7 8 9 10,判断是出现了负环,不知道为什么 /kk
#include<bits/stdc++.h>
using namespace std;
#define N 80053
#define M 7000003
#define LL long long
#define INF 0x3f3f3f3f
int n,m,p[43],te[103][43],sum,ds[N],ck[N];
int S,T,q[N],d[N],incf[N],pre[N];
int h[N],to[M],ne[M],f[M],w[M],idx;
bool st[N];
void add(int u,int v,int c,int d){ //加边
to[idx]=v,f[idx]=c,w[idx]=d,ne[idx]=h[u],h[u]=idx++;
to[idx]=u,f[idx]=0,w[idx]=-d,ne[idx]=h[v],h[v]=idx++;
}
bool spfa(){ //费用流模板
int hh=0,tt=1;
for(int i=S;i<=T;++i) d[i]=INF,incf[i]=pre[i]=0;
q[hh]=S,d[S]=0,incf[S]=INF;
while(hh!=tt){
int u=q[hh++];
if(hh==N) hh=0;
st[u]=false;
for(int i=h[u];~i;i=ne[i]){
int v=to[i];
if(f[i]&&d[v]>d[u]+w[i]){
d[v]=d[u]+w[i],pre[v]=i;
incf[v]=min(incf[u],f[i]);
if(!st[v]){
q[tt++]=v,st[v]=true;
if(tt==N) tt=0;
}
}
}
}
return incf[T]>0;
}
int EK(){ //跑SPFA的同时动态加边
int cost=0;
while(spfa()){
int t=incf[T];
cost+=t*d[T];
for(int i=T;i!=S;i=to[pre[i]^1])
f[pre[i]]-=t,f[pre[i]^1]+=t;
int tmp=to[pre[T]^1];
add(tmp+1,T,1,0);
for(int i=1;i<=n;++i)
add(i+m*sum,tmp+1,1,te[i][ck[tmp]]*(ds[tmp]+1));
}
return cost;
}
int main(){
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&p[i]),sum+=p[i];
S=0,T=sum*m+n+1;
for(int i=1;i<=n;++i) add(S,i+sum*m,p[i],0);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
scanf("%d",&te[i][j]);
add(i+sum*m,(j-1)*sum+1,1,te[i][j]);
}
for(int i=1;i<=m;++i)
for(int j=1;j<=sum;++j){
int tmp=(i-1)*sum+j;
ck[tmp]=i,ds[tmp]=j;
}
for(int i=1;i<=m;++i) add((i-1)*sum+1,T,1,0);
printf("%d\n",EK());
return 0;
}