Sub-tree generation:
When the Minimum Spanning Tree is obtained, the array path [I] [J] is used to represent the maximum edge weight from I to J in the MST.
After the result is obtained, enumerate all edges that are not in the MST and add them to the MST to form a new tree with a ring, this ring is caused by the newly added edge (I, j). Therefore, you can delete path [I] [J] to obtain a new tree, and one of all such trees will be a child tree.
For example:
G and H are not edges on the MST. By adding an edge (G, H), A ring (B, H, g) is obtained ), then, because G has been calculated when the minimum spanning tree is calculated, the maximum edge weight between H is path [g] [H] = BH, so you can get a Minimum Spanning Tree by deleting BH, and then update the answer.
# Include <iostream> # Include <Cstring> # Include <Cstdio> Using Namespace STD; Const Int X = 105 ; Const Int INF = 100000000 ; Int Map [x] [X], DIS [x]; Int Path [x] [x]; /// Record the maximum edge weight on the I, J Path Int Pre [x]; /// Precursor Vertex Int N; /// Number of vertices Bool Use [X], In [X] [x]; Int Prim () {memset (use, False , Sizeof (Use); memset (PRE, 0 , Sizeof (Pre); memset ( In , False , Sizeof ( In )); For ( Int I = 0 ; I <= N; I ++ ) Dis [I] = INF; DIS [ 1 ] = 0 ; Int Ans = 0 ; Int Min, K, P; For (Int I = 0 ; I <n; I ++ ) {Min = INF; For ( Int J = 1 ; J <= N; j ++ ) If (! Use [J] & min> Dis [J]) min = Dis [k = J]; If (Min = INF) Return INF; P = Pre [k]; In [P] [k] = In [K] [p] = True ; Path [p] [k] = Path [k] [p] = min; // Since the vertex K has not been calculated, it is directly equal to Min For ( Int J = 1 ; J <= N; j ++ ) If (Use [J]) // Update vertices already in the MST Path [J] [k] = path [k] [J] = Max (path [J] [K], path [p] [k]); use [k] = True ; Ans + = Min; For ( Int J = 1 ; J <= N; j ++ ) If (! Use [J] & dis [J]> Map [k] [J]) dis [J] = Map [k] [J], pre [J] = K ;} Return Ans ;} Int Main (){ // Freopen ("sum. In", "r", stdin ); // Freopen ("sum. Out", "W", stdout ); Int T, M, x, y, z; CIN > T; While (T -- ) {Scanf ( " % D " , & N ,& M ); For ( Int I = 1 ; I <= N; I ++ ) For ( Int J = 1 ; J <= N; j ++ ) Map [I] [J] = Map [J] [I] = INF; While (M --) {Scanf ( " % D " , & X, & Y ,& Z); map [x] [Y] = Map [y] [x] = Z ;} Int Ans = Prim (); Int OK = True ; For ( Int I = 1 ; I <= N & OK; I ++) // Enumeration finds edge not on the MST For ( Int J = 1 ; J <= N & OK; j ++ ) If (Map [I] [J]! = Inf &&! In [I] [J]) If (ANS = ANS-path [I] [J] + Map [I] [J]) OK = False ; If (OK) printf ( " % D \ n " , ANS ); Else Printf ( " Not unique! \ N " );} Return 0 ;}