For details about the max weight closure diagram, see hu botao's paper "Application of the minimal cut model in the informatics Competition". Here I will define it and some other things.
Suppose we have a graph where the outbound edges of the point set are connected to the point set. This is called a closed graph. Now all these points have a weight. We need to select a closed graph to maximize the weight.
Back to this question:
We can see that the user group and transfer station are weighted point sets, the user group's right is the benefit, and the transfer station's right is the negative cost, that is, 0-the cost, if the user group connects an arc to two transfer stations, this is a closed chart.
We require that the weight and maximum value of the closed graph, that is, the maximum benefit, be transferred to the above method of finding the maximum weight closed graph.
The practice is:
- The point from the source S to the positive weight. The capacity is the secondary weight.
- The capacity is the absolute value of the negative weight value from the point of the negative weight to the sink T.
- In the closed graph, all the arcs are replaced with those with OO capacities.
- The answer is the sum of all positive values-Minimum Cut Capacity (maximum Stream)
The problem is solved.
(Pay attention to the scope .,.. I re again, and many times the array is opened small Ah> A <.)
#include <cstdio>using namespace std;const int N=60000, M=350000, oo=1000000000;#define min(a,b) ((a)<(b)?(a):(b))int ihead[N], inext[M], from[M], to[M], cap[M], cnt=1;int cur[N], gap[N], d[N], p[N];int isap(int s, int t, int n) {int i, maxflow=0, f, u;for(i=0; i<=n; ++i) cur[i]=ihead[i];gap[0]=n; u=s;while(d[s]<n) {for(i=cur[u]; i; i=inext[i]) if(d[to[i]]+1==d[u] && cap[i]) break;if(i) {cur[u]=i; p[to[i]]=i; u=to[i];if(u==t) {for(f=oo; u!=s; u=from[p[u]]) f=min(f, cap[p[u]]);for(u=t; u!=s; u=from[p[u]]) cap[p[u]]-=f, cap[p[u]^1]+=f;maxflow+=f;}}else {if(!(--gap[d[u]])) break;d[u]=n;for(i=ihead[u]; i; i=inext[i]) if(cap[i] && d[u]>d[to[i]]+1)d[u]=d[to[i]]+1, cur[u]=i;++gap[d[u]]; if(u!=s) u=from[p[u]];}}return maxflow;}void add(int u, int v, int c) {inext[++cnt]=ihead[u]; ihead[u]=cnt; from[cnt]=u; to[cnt]=v; cap[cnt]=c;inext[++cnt]=ihead[v]; ihead[v]=cnt; from[cnt]=v; to[cnt]=u; cap[cnt]=0;}int main() {int n, m, sum=0;scanf("%d%d", &n, &m);int i, a, b, c;for(i=1; i<=n; ++i) {scanf("%d", &c);add(m+i, n+m+1, c);}for(i=1; i<=m; ++i) {scanf("%d%d%d", &a, &b, &c);sum+=c;add(i, m+a, oo); add(i, m+b, oo);add(0, i, c);}printf("%d\n", sum-isap(0, n+m+1, n+m+2));return 0;}