洛谷 P4174 [NOI2006]最大获利

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

https://wenku.baidu.com/view/87ecda38376baf1ffc4fad25.html第24-28页,有Maxflow(n,n+m)版的模型。

 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 {
14     int n,le,s,t,first[maxn],dis[maxn],cur[maxn],que[maxn],head,tail; NetEdge edge[maxm];
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));
21         head=0; tail=1; que[0]=s; dis[s]=1;
22         while (head!=tail)
23         {
24             int x=que[head++];
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
",(1ll*U*n-g.Dinic(n+1,n+2))>>1);
81     return 0;
82 }
View Code
原文地址:https://www.cnblogs.com/Blue233333/p/12262579.html