# 洛谷 P4174 [NOI2006]最大获利

https://www.luogu.com.cn/problem/P4174

 1 #include<cstdio>
2 #include<cstring>
3 #include<cstdlib>
4 #include<algorithm>
5 using namespace std;
6 #define LL long long
7
8 int n,m;
9 #define maxn 5011
10 #define maxm 50011*4+maxn*4
11 struct NetEdge{int to,next,cap,flow;};
12 struct Net
13 {
15     void clear(int N) {n=N; le=2; memset(first,0,sizeof(first));}
16     void in(int x,int y,int c) {NetEdge &e=edge[le]; e.to=y; e.cap=c; e.flow=0; e.next=first[x]; first[x]=le++;}
17     void insert(int x,int y,int c) {in(x,y,c); in(y,x,0);}
18     bool bfs()
19     {
20         memset(dis,0,sizeof(dis));
23         {
25             for (int i=first[x];i;i=edge[i].next)
26             {
27                 NetEdge &e=edge[i]; if (dis[e.to] || e.cap==e.flow) continue;
28                 dis[e.to]=dis[x]+1; que[tail++]=e.to;
29             }
30         }
31         return dis[t]>0;
32     }
33     LL dfs(int x,int a)
34     {
35         if (x==t || !a) return (LL)a;
36         LL flow=0,f;
37         for (int &i=cur[x];i;i=edge[i].next)
38         {
39             NetEdge &e=edge[i];
40             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
41             {
42                 e.flow+=f;
43                 flow+=f;
44                 edge[i^1].flow-=f;
45                 a-=f;
46                 if (!a) break;
47             }
48         }
49         return flow;
50     }
51     LL Dinic(int S,int T)
52     {
53         s=S; t=T;
54         LL flow=0;
55         while (bfs())
56         {
57             for (int i=1;i<=n;i++) cur[i]=first[i];
58             flow+=dfs(s,0x3f3f3f3f);
59         }
60         return flow;
61     }
62 }g;
63
64 int p[maxn],du[maxn];
65 int main()
66 {
67     scanf("%d%d",&n,&m);
68     for (int i=1;i<=n;i++) scanf("%d",&p[i]);
69     int U=0;
70     g.clear(n+2);
71     for (int i=1,x,y,v;i<=m;i++)
72     {
73         scanf("%d%d%d",&x,&y,&v);
74         g.insert(x,y,v);
75         g.insert(y,x,v);
76         U+=v;
77         du[x]+=v; du[y]+=v;
78     }
79     for (int i=1;i<=n;i++) g.insert(n+1,i,U),g.insert(i,n+2,U+2*p[i]-du[i]);
80     printf("%lld\n",(1ll*U*n-g.Dinic(n+1,n+2))>>1);
81     return 0;
82 }
View Code

posted @ 2020-02-05 09:48  Blue233333  阅读(108)  评论(0编辑  收藏  举报