The classic example seems to be able to be converted to maxflow (N, N + M). At present, we can barely understand the practice of maxflow (n + M, N + M.
Question: Input n vertices and m edges in an undirected graph. The vertex weight is negative, the edge weight is positive, and the weight of the output largest weight closed subgraph.
(Largest weighted closed subgraph: the successor of each point in the graph must also be shown in the figure)
Architecture strategy: View edges as points (some questions have no right, and the modeling is slightly different ),
Connect Three edges (S, N + I, W) to the original edge e [I] (U, V, W), (N + I, U, INF ), (N + I, V, INF ).
Connect one edge (v, T, P [v]) to the original vertex v.
That is, the positive weight point is connected to the source point, and the negative weight point is connected to the sink point.
Sum-maxflow is the answer.
Obviously, the SAP graph has n + m + 2 and (n + M * 3) * 2.
For more information about the derivation, see the previous documents or other websites.
#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <set>#include <queue>using namespace std;#define ll long long#define MP make_pair#define mxn 56000#define mxe (51000*4*2)#define inf 1e9#define eps 1e-8struct SAP{ int dis[mxn],pre[mxn],gap[mxn],arc[mxn]; int f[mxe],cap[mxe]; int head[mxn],nxt[mxe],vv[mxe],e; void init(){e=0;memset(head,-1,sizeof(head));} void add(int u,int v,int c){ vv[e]=v,cap[e]=c,nxt[e]=head[u],head[u]=e++; vv[e]=u,cap[e]=0,nxt[e]=head[v],head[v]=e++; } ll max_flow(int s,int t,int n){ int q[mxn],j,mindis; ll ans=0; int ht=0,tl=1,u,v; int low; bool found,vis[mxn]; memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); memset(vis,0,sizeof(vis)); memset(arc,-1,sizeof(arc)); memset(f,0,sizeof(f)); q[0]=t;vis[t]=true;dis[t]=0;gap[0]=1; while(ht<tl){ u=q[ht++]; for(int i=head[u];i!=-1;i=nxt[i]){ v = vv[i]; if(!vis[v]){ vis[v]=true; dis[v]=dis[u]+1; q[tl++]=v; gap[dis[v]]++; arc[v]=head[v]; } } } u=s;low=inf;pre[s]=s; while(dis[s]<n){ found=false; for(int &i=arc[u];i!=-1;i=nxt[i]){ if(dis[vv[i]]==dis[u]-1 && cap[i]>f[i]){ found=true;v=vv[i]; low=min(low,cap[i]-f[i]); pre[v]=u;u=v; if(u==t){ while(u!=s){ u=pre[u]; f[arc[u]]+=low; f[arc[u]^1]-=low; } ans+=low;low=inf; } break; } } if(found) continue; mindis=n; for(int i=head[u];i!=-1;i=nxt[i]){ if(mindis>dis[vv[i]] && cap[i]>f[i]){ mindis=dis[vv[j=i]]; arc[u]=i; } } if(--gap[dis[u]]==0) return ans; dis[u]=mindis+1; gap[dis[u]]++; u=pre[u]; } return ans; }}sap;int p[5050];int main(){int n,m;while(~scanf("%d%d",&n,&m)){for(int i=1;i<=n;++i) scanf("%d",p+i);ll sum = 0;sap.init(); for(int i=1;i<=m;++i){int a,b,c;scanf("%d%d%d",&a,&b,&c);sap.add(n+m+1,n+i,c);sap.add(n+i,a,inf);sap.add(n+i,b,inf);sum+=c; } for(int i=1;i<=n;++i)sap.add(i,n+m+2,p[i]);ll mf = sap.max_flow(n+m+1,n+m+2,n+m+2);printf("%I64d\n",sum-mf); } return 0;}
HDU 3879 base station (maximum weighted closed subgraph)