thinking
For each transit station, connect a weight to \ (T \) to the side of the cost of building this transit station. Cutting this edge means that the transfer station will be built.
For each person, connect an edge with a weight of \ (INF \) to his two transfer stations. Then connect an edge from \ (S \) to this person whose weight is the income of this person. Cutting this edge means not to have this income.
This is the model of the most weighted closed subgraph.
Final answer = total revenue - cut revenue - cost of building transfer station = total revenue - Minimum Cut
Code
#include<cstring> #include<algorithm> #include<queue> #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> using namespace std; typedef long long ll; const int N = 100010,M = 1000010,INF = 1e9; ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } struct node { int v,nxt,w; }e[M << 1]; int head[N],ejs = 1; void add(int u,int v,int w) { e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w; e[++ejs].v = u;e[ejs].nxt = head[v];head[v] = ejs;e[ejs].w = 0; } int S,T; int n,m,cur[N]; queue<int>q; int dep[N]; int bfs() { while(!q.empty()) q.pop(); memset(dep,0,sizeof(dep)); dep[S] = 1;q.push(S); while(!q.empty()) { int u = q.front();q.pop(); for(int i = head[u];i;i = e[i].nxt) { int v = e[i].v; if(!dep[v] && e[i].w) { dep[v] = dep[u] + 1;q.push(v); if(v == T) return 1; } } } return 0; } int dfs(int u,int now) { if(u == T) return now; int ret = 0; for(int &i = cur[u];i;i = e[i].nxt) { int v = e[i].v; if(dep[v] == dep[u] + 1 && e[i].w) { int k = dfs(v,min(now - ret,e[i].w)); ret += k; e[i].w -= k; e[i ^ 1].w += k; if(ret == now) return ret; } } return ret; } int dinic() { int ans = 0; while(bfs()) { for(int i = 1;i <= T;++i) cur[i] = head[i]; ans += dfs(S,INF); } return ans; } int main() { n = read(),m = read(); T = n + m + 2,S = T - 1; int tot = 0; for(int i = 1;i <= n;++i) { int w = read(); add(i,T,w); } for(int i = 1;i <= m;++i) { int x = read(),y = read(),w = read(); add(i + n,x,INF);add(i + n,y,INF); add(S,i + n,w); tot += w; } cout<<tot - dinic(); return 0; }