From Jiuye ~
Given n skills and M restrictions
Below is the full level of each skill
At the beginning, each skill level is 0.
MB limit
(C, L1) (D, L2) Cost
If the C skill level is greater than or equal to level 1, the cost of C skill level from level 0 to Level 2 is cost.
.. What he said makes sense. I have nothing to say )_
Minimum tree structure, with 0 as the root, the cost of triggering each skill level 0 is 0
If the skill level X has been lit up, the skill level X-1 cost is 0
# Include <stdio. h> # include <string. h> # include <iostream> # include <algorithm> # include <math. h> using namespace STD;/** minimum tree operator * complexity O (Nm) * vertex subscript [0, n-1] edge subscript [0 M-1] * directed edge representation: u-> V costs Cost * to return the Edge Weight of the smallest tree shard.-1 indicates that the smallest tree shard does not exist */const int INF = 100000000; const int maxn = 1010; // point const int maxm = 1010000; // number of sides # define ll intstruct edge {int U, V; ll cost;} edge [maxm]; int pre [maxn], id [maxn], visit [maxn], edgenum; void add (int u, Int V, ll cost) {edge e = {u, v, cost}; edge [edgenum ++] = E;} ll in [maxn]; ll Zhuliu (INT root, int N, int M, edge []) // Number of edges of the root (note that the root cannot be any tree) edge {int U, V; ll res = 0; while (1) {for (INT I = 0; I <n; I ++) in [I] = inf; For (INT I = 0; I <m; I ++) if (edge [I]. u! = Edge [I]. V & edge [I]. cost <in [edge [I]. v]) {pre [edge [I]. v] = edge [I]. u; in [edge [I]. v] = edge [I]. cost;} For (INT I = 0; I <n; I ++) if (I! = Root & in [I] = inf) Return-1; // the smallest tree does not exist int Tn = 0; memset (ID,-1, sizeof (ID )); memset (visit,-1, sizeof (visit); in [root] = 0; For (INT I = 0; I <n; I ++) {res + = in [I]; V = I; while (visit [v]! = I & ID [v] =-1 & V! = Root) {visit [v] = I; V = pre [v];} If (V! = Root & ID [v] =-1) {for (INT u = pre [v]; u! = V; u = pre [u]) ID [u] = tn; Id [v] = tn ++;} If (Tn = 0) break; // No directed ring for (INT I = 0; I <n; I ++) if (ID [I] =-1) id [I] = tn ++; For (INT I = 0; I <m;) {v = edge [I]. v; edge [I]. U = ID [edge [I]. u]; edge [I]. V = ID [edge [I]. v]; If (edge [I]. u! = Edge [I]. v) edge [I ++]. cost-= in [v]; else swap (edge [I], edge [-- m]);} n = tn; root = ID [root];} return res; //-1 indicates that the smallest tree does not exist} void Init () {edgenum = 0;} # define n 55int n, m, a [n], sum [N]; int Hash (int I, Int J) {return sum [I-1] + J;} int main () {int I, j, C, L1, D, L2, cost; while (scanf ("% d", & N, & M), N + M) {Init (); sum [0] = 0; for (I = 1; I <= N; I ++) scanf ("% d", & A [I]), a [I] ++, sum [I] = sum [I-1] + A [I]; for (I = 1; I <= N; I ++) add (0, hash (I, 1), 0); for (I = 1; I <= N; I ++) for (j = 2; j <= A [I]; j ++) add (Hash (I, j), hash (I, J-1), 0); While (M --) {scanf ("% d ", & C, & L1, & D, & L2, & cost); L1 ++; L2 ++; add (Hash (C, L1), hash (D, L2 ), cost);} printf ("% d \ n", Zhuliu (0, sum [N] + 1, edgenum, edge);} return 0 ;}
HDU 4966 GGS-DDU minimum tree structure