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,费用为定位费的点,再把原有的航路建出来。

posted on 2016-03-18 05:58  xiyuedong  阅读(162)  评论(0编辑  收藏  举报