传送门biu~
最小割模型,每个中转站建一个点,每个用户建一个点。有关系的中转站和用户之间连INF,S连每个中转站流量为成本,用户连T流量为利润。先获得所有利润,割掉中转站成本或者用户获利,所有利润减最小割即为答案。
#include<bits/stdc++.h>
using namespace std;
const int INF=1e9;
int n,m,S,T,ans;
int head[60005],fir[60005],dep[60005],nex[500005],to[500005],cap[500005],tp=1;
inline void add(int x,int y,int c){
nex[++tp]=head[x];
head[x]=tp;
to[tp]=y;
cap[tp]=c;
}
inline void Insert(int u,int v,int w){add(u,v,w);add(v,u,0);}
inline int bfs(){
memset(dep,0,sizeof(dep));
dep[S]=1;queue<int>q;
q.push(S);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=nex[i]){
if(cap[i] && !dep[to[i]]){
dep[to[i]]=dep[x]+1;
q.push(to[i]);
}
}
}
return dep[T];
}
int dfs(int x,int now){
if(x==T || !now) return now;
int c=0;
for(int &i=fir[x];i;i=nex[i]){
if(dep[to[i]]==dep[x]+1 && cap[i]){
int f=dfs(to[i],min(now,cap[i]));
now-=f;
cap[i]-=f;
cap[i^1]+=f;
c+=f;
if(!now) break;
}
}
return c;
}
inline int Dinic(){
int c=0;
while(bfs()){
for(int i=S;i<=T;++i) fir[i]=head[i];
c+=dfs(S,INF);
}
return c;
}
int main(){
scanf("%d%d",&n,&m);S=0;T=n+m+1;
for(int i=1;i<=n;++i){
int x;
scanf("%d",&x);
Insert(S,i,x);
}
for(int i=1;i<=m;++i){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
ans+=z;
Insert(x,n+i,INF);
Insert(y,n+i,INF);
Insert(n+i,T,z);
}
printf("%d",ans-Dinic());
return 0;
}