洛谷 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\n",(1ll*U*n-g.Dinic(n+1,n+2))>>1); 81 return 0; 82 }