1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define M 100008 5 #define inf 2139062143 6 using namespace std; 7 int T,head[M],next[10*M],u[10*M],v[10*M],d[M],n,m,cnt=1,ans,q[2*M],sum; 8 void jia(int a1,int a2,int a3) 9 { 10 cnt++; 11 u[cnt]=a2; 12 v[cnt]=a3; 13 next[cnt]=head[a1]; 14 head[a1]=cnt; 15 } 16 bool bfs() 17 { 18 memset(d,0,sizeof(int)*(T+2)); 19 int h=0,t=1; 20 q[1]=0; 21 d[0]=1; 22 for(;h<t;) 23 { 24 h++; 25 int p=q[h]; 26 for(int i=head[p];i;i=next[i]) 27 if(!d[u[i]]&&v[i]) 28 { 29 d[u[i]]=d[p]+1; 30 if(d[T]) 31 return 1; 32 t++; 33 q[t]=u[i]; 34 } 35 } 36 return 0; 37 } 38 int dinic(int s,int f) 39 { 40 if(s==T) 41 return f; 42 int rest=f; 43 for(int i=head[s];i&&rest;i=next[i]) 44 if(v[i]&&d[u[i]]==d[s]+1) 45 { 46 int now=dinic(u[i],min(rest,v[i])); 47 if(!now) 48 d[u[i]]=0; 49 v[i]-=now; 50 v[i^1]+=now; 51 rest-=now; 52 } 53 return f-rest; 54 } 55 int main() 56 { 57 scanf("%d%d",&n,&m); 58 T=n+m+1; 59 for(int i=1;i<=n;i++) 60 { 61 int a1; 62 scanf("%d",&a1); 63 jia(i,T,a1); 64 jia(T,i,0); 65 } 66 for(int i=1;i<=m;i++) 67 { 68 int a1,a2,a3,a4; 69 a3=n+i; 70 scanf("%d%d%d",&a1,&a2,&a4); 71 sum+=a4; 72 jia(a3,a1,inf); 73 jia(a1,a3,0); 74 jia(a3,a2,inf); 75 jia(a2,a3,0); 76 jia(0,a3,a4); 77 jia(a3,0,0); 78 } 79 for(;bfs();) 80 ans+=dinic(0,inf); 81 printf("%d\n",sum-ans); 82 return 0; 83 }
最小割 站向汇点连容量为费用的边,源点向用户群连容量为获利的边,用户群与站之间有关联的连容量为inf的边,跑最小割,用总收益减去即为答案。