Max weight closure diagram of HDU 3879 Base Station
Question link: Click the open link
Question:
Given n weighted vertices, m undirected weighted Edges
If you select a subgraph, the weight of the subgraph is edge and point.
Returns the maximum weight.
Edge is also treated as a vertex. Next is the max weight closure diagram.
Dinic:
# Include
# Include
# Include
Using namespace std; // starts from 0. init (n) n = maximum vertex mark + 10 const int N = 200010; const int M = 500010; const int INF = ~ 0u> 2; template
Struct Max_Flow {int n; int Q [N], sign; int head [N], level [N], cur [N], pre [N]; int nxt [M], pnt [M], E; T cap [M]; void Init (int n) {this-> n = n; E = 0; std :: fill (head, head + n,-1);} // directed rw = 0 void add (int from, int to, T c, T rw) {pnt [E] = to; cap [E] = c; nxt [E] = head [from]; head [from] = E ++; pnt [E] = from; cap [E] = rw; nxt [E] = head [to]; head [to] = E ++;} bool Bfs (int s, int t) {sign = t; Std: fill (level, level + n,-1); int * front = Q, * tail = Q; * tail ++ = t; level [t] = 0; while (front <tail & level [s] =-1) {int u = * front ++; for (int e = head [u]; e! =-1; e = nxt [e]) {if (cap [e ^ 1]> 0 & level [pnt [e] <0) {level [pnt [e] = level [u] + 1; * tail ++ = pnt [e] ;}} return level [s]! =-1;} void Push (int t, T & flow) {T mi = INF; int p = pre [t]; for (int p = pre [t]; p! =-1; p = pre [pnt [p ^ 1]) {mi = std: min (mi, cap [p]);} for (int p = pre [t]; p! =-1; p = pre [pnt [p ^ 1]) {cap [p]-= mi; if (! Cap [p]) {sign = pnt [p ^ 1];} cap [p ^ 1] + = mi;} flow + = mi;} void Dfs (int u, int t, T & flow) {if (u = t) {Push (t, flow); return;} for (int & e = cur [u]; e! =-1; e = nxt [e]) {if (cap [e]> 0 & level [u]-1 = level [pnt [e]) {pre [pnt [e] = e; Dfs (pnt [e], t, flow); if (level [sign]> level [u]) {return ;} sign = t ;}}t Dinic (int s, int T) {pre [s] =-1; t flow = 0; while (Bfs (s, T )) {std: copy (head, head + n, cur); Dfs (s, t, flow);} return flow ;}}; Max_Flow
F; int n, m; int work () {F. init (n + m + 10); int from = 0, to = n + m + 1, A; for (int I = 1; I <= n; I ++) {scanf ("% d", & A); F. add (I, to, A, 0) ;}int u, v, d, all = 0; for (int I = 1; I <= m; I ++) {scanf ("% d", & u, & v, & d); all + = d; F. add (from, n + I, d, 0); F. add (n + I, u, INF, 0); F. add (n + I, v, INF, 0);} return all-F. dinic (from, to);} int main () {while (cin> n> m) cout <
# Include
# Include
# Include
# Include
Using namespace std; # define ll intconst int MAXN = 100010; // maximum number of points const int MAXM = 400010; // maximum number of sides const int INF = 0x3f3f3f; struct Edge {int to, next, cap, flow;} edge [MAXM]; // note that it is MAXMint tol; int head [MAXN]; int gap [MAXN], dep [MAXN], cur [MAXN]; void add (int u, int v, int w, int rw = 0) {edge [tol]. to = v; edge [tol]. cap = w; edge [tol]. flow = 0; edge [tol]. next = head [u]; head [u] = tol ++; edge [tol]. to = u; edge [t Ol]. cap = rw; edge [tol]. flow = 0; edge [tol]. next = head [v]; head [v] = tol ++;} int Q [MAXN]; void BFS (int start, int end) {memset (dep,-1, sizeof (dep); memset (gap, 0, sizeof (gap); gap [0] = 1; int front = 0, rear = 0; dep [end] = 0; Q [rear ++] = end; while (front! = Rear) {int u = Q [front ++]; for (int I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. to; if (dep [v]! =-1) continue; Q [rear ++] = v; dep [v] = dep [u] + 1; gap [dep [v] ++ ;}}} int S [MAXN]; int sap (int start, int end, int N) {BFS (start, end); memcpy (cur, head, sizeof (head )); int top = 0; int u = start; int ans = 0; while (dep [start] <N) {if (u = end) {int Min = INF; int inser; for (int I = 0; I <top; I ++) if (Min> edge [S [I]. cap-edge [S [I]. flow) {Min = edge [S [I]. cap-edge [S [I]. flow; inser = I;} for (int I = 0; I <top; I ++) {edge [S [I]. flow + = Min; edge [S [I] ^ 1]. flow-= Min;} ans + = Min; top = inser; u = edge [S [top] ^ 1]. to; continue;} bool flag = false; int v; for (int I = cur [u]; I! =-1; I = edge [I]. next) {v = edge [I]. to; if (edge [I]. cap-edge [I]. flow & dep [v] + 1 = dep [u]) {flag = true; cur [u] = I; break ;}} if (flag) {S [top ++] = cur [u]; u = v; continue;} int Min = N; for (int I = head [u]; I! =-1; I = edge [I]. next) if (edge [I]. cap-edge [I]. flow & dep [edge [I]. to] <Min) {Min = dep [edge [I]. to]; cur [u] = I;} gap [dep [u] --; if (! Gap [dep [u]) return ans; dep [u] = Min + 1; gap [dep [u] ++; if (u! = Start) u = edge [S [-- top] ^ 1]. to;} return ans;} void init () {tol = 0; memset (head,-1, sizeof (head);} int n, m; ll work () {init (); int from = 0, to = n + m + 1, A; for (int I = 1; I <= n; I ++) {scanf ("% d", & A); add (I, to, A) ;}int u, v; ll d; ll all = 0; for (int I = 1; I <= m; I ++) {scanf ("% d", & u, & v, & d ); all + = d; add (from, n + I, d); add (n + I, u, INF); add (n + I, v, INF );} return all-sap (from, to, to + 1);} int main () {while (cin> n> m) cout <