Ural_1471
This topic can be divided by tree links. We also recommend an easy-to-understand blog about tree links: http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html.
# Include <stdio. h> # Include < String . H> # Define Maxd 50010 # Define Maxm 100010 Int N, Q, first [maxd], next [maxm], V [maxm], E; Int Fa [maxd], DEP [maxd], son [maxd], size [maxd], W [maxd], top [maxd], CNT; Int Q [maxd], sum [ 4 * Maxd]; Struct Edge { Int X, Y, Z;} edge [maxd]; Void Swap ( Int & X, Int & Y ){ Int T; t = X, x = Y, y = T ;} Void Add ( Int X, Int Y) {v [E] = Y; next [E] = First [X], first [x] = e ++ ;} Void Update ( Int Cur) {sum [cur] = Sum [cur < 1 ] + Sum [cur < 1 | 1 ];} Void Prepare (){ Int I, j, X, rear = 0 ; Fa [ 1 ] = 0 , DEP [ 1 ] = 1 ; Q [rear ++] = 1 ; For (I = 0 ; I <rear; I ++ ) {X =Q [I]; For (J = first [X]; J! =- 1 ; J = Next [J]) If (V [J]! = Fa [x]) {Fa [V [J] = X, DEP [V [J] = Dep [x] + 1 ; Q [rear ++] = V [J] ;}} size [ 0 ] = 0 ; For (I = rear- 1 ; I> = 0 ; I -- ) {X = Q [I]; Size [x] = 1 , Son [x] = 0 ; For (J = first [X]; J! =- 1 ; J = Next [J]) If (V [J]! = Fa [x]) {size [x] + =Size [V [J]; If (Size [V [J]> Size [son [x]) Son [x] = V [J] ;}} CNT = 0 ; Memset (top, 0 , Sizeof (Top )); For (I = 0 ; I <rear; I ++ ) {X = Q [I]; If (Top [x] = 0 ){ For (J = x; J! = 0 ; J = Son [J]) Top [J] = X, W [J] = ++ CNT ;}}} Void Refresh ( Int Cur, Int X, Int Y, Int K, Int V ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X = Y) {sum [cur] = V; Return ;} If (K <=Mid) Refresh (LS, X, mid, K, V ); Else Refresh (RS, mid + 1 , Y, K, V); Update (cur );} Void Init (){ Int I, x, y, z; e = 0 ; Memset (first, - 1 , Sizeof (First )); For (I = 1 ; I <n; I ++ ) {Scanf ( " % D " , & X, & Y ,& Z ); ++ X, ++ Y; edge [I]. x = X, edge [I]. Y = Y, edge [I]. z = Z; add (x, y), add (Y, x);} prepare (); memset (sum, 0 , Sizeof (SUM )); For (I = 1 ; I <n; I ++ ){ If (DEP [edge [I]. x]> Dep [edge [I]. Y]) Swap (edge [I]. X, edge [I]. Y); refresh ( 1 , 1 , N, W [edge [I]. Y], edge [I]. z );}} Void Search ( Int Cur, Int X, Int Y, Int S,Int T, Int & Ans ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X> = S & Y <= T) {ans + = Sum [cur]; Return ;} If (Mid> = S) Search (LS, X, mid, S, T, ANS ); If (Mid + 1 <= T) Search (RS, mid + 1 , Y, S, T, ANS );} Void Deal ( Int X, Int Y ){ Int FX = top [X], FY = top [Y], ANS =0 ; While (FX! = FY ){ If (DEP [FX]> Dep [FY]) Swap (FX, FY), swap (x, y); search ( 1 , 1 , N, W [FY], W [Y], ANS); y = Fa [FY], FY = Top [y];} If (X! = Y ){ If (DEP [x]>Dep [y]) Swap (x, y); search ( 1 , 1 , N, W [son [X], W [Y], ANS);} printf ( " % D \ n " , ANS );} Void Solve (){ Int I, Q, X, Y; scanf ( " % D " ,&Q ); For (I = 0 ; I <q; I ++ ) {Scanf ( " % D " , & X ,& Y); Deal (x + 1 , Y + 1 );}} Int Main (){ While (Scanf ( " % D " , & N) = 1 ) {Init (); solve ();} Return 0 ;}