1 #include<cstdio> 2 #include<iostream> 3 #define M 1605 4 #define S 3000005 5 using namespace std; 6 int q[S],f[M],n,m,ans,a[M],head[M],next[S],u[S],v[S],c[S],fr[S],cnt=1,d[M],fro[M],T; 7 void jia(int a1,int a2,int a3,int a4) 8 { 9 cnt++; 10 next[cnt]=head[a1]; 11 head[a1]=cnt; 12 u[cnt]=a2; 13 v[cnt]=a3; 14 c[cnt]=a4; 15 fr[cnt]=a1; 16 return; 17 } 18 bool bfs() 19 { 20 for(int i=1;i<=T;i++) 21 d[i]=0x7fffffff; 22 f[0]=1; 23 int h=0,t=1; 24 q[1]=0; 25 for(;h!=t;) 26 { 27 h++; 28 int p=q[h]; 29 f[p]=0; 30 for(int i=head[p];i;i=next[i]) 31 if(v[i]&&d[u[i]]>d[p]+c[i]) 32 { 33 fro[u[i]]=i; 34 d[u[i]]=d[p]+c[i]; 35 if(!f[u[i]]) 36 { 37 t++; 38 q[t]=u[i]; 39 } 40 } 41 } 42 if(d[T]==0x7fffffff) 43 return 0; 44 else 45 return 1; 46 } 47 void zhao() 48 { 49 int ma=0x7fffffff; 50 for(int i=fro[T];i;i=fro[fr[i]]) 51 ma=min(ma,v[i]); 52 for(int i=fro[T];i;i=fro[fr[i]]) 53 { 54 v[i]-=ma; 55 v[i^1]+=ma; 56 ans+=ma*c[i]; 57 } 58 return; 59 } 60 int main() 61 { 62 scanf("%d%d",&n,&m); 63 T=2*n+1; 64 for(int i=1;i<=n;i++) 65 scanf("%d",&a[i]); 66 for(int i=1;i<=n;i++) 67 { 68 jia(0,i,1,0); 69 jia(i,0,0,0); 70 jia(i+n,T,1,0); 71 jia(T,i+n,0,0); 72 jia(0,i+n,1,a[i]); 73 jia(i+n,0,0,-a[i]); 74 } 75 for(int i=1;i<=m;i++) 76 { 77 int a1,a2,a3; 78 scanf("%d%d%d",&a1,&a2,&a3); 79 if(a1>a2) 80 swap(a1,a2); 81 jia(a1,a2+n,1,a3); 82 jia(a2+n,a1,0,-a3); 83 } 84 for(;bfs();) 85 zhao(); 86 printf("%d\n",ans); 87 return 0; 88 }
费用流,拆点 源点分别向拆出的点连费用为0,费用为定位费的点,再把原有的航路建出来。