Topic: https://codeforc.es/gym/101810/problem/M
Meaning of the questions: give your tree, here are m queries, seeking u-> v is the maximum number, there are two points between the input side, the positive side there is the right, there are anti-anti-edge right, then Q u-> v can be subjected to the maximum weight is how much
Ideas: We begin to root for u we will find when we go where the non-v subtree we can all come back and finish the edges, where the sub-tree for v we can also reverse two sides are completed, uv's the shortest road can only go again, so this problem is transformed to find the longest chain issues, u-> v longest chain, but we have m queries, we can not always get through all the points come longest chain, we can in fact is the root, then the two arrays are recorded by positive and negative weights to the root of the distance from the current point, and then drawing it can be seen from their points of fact dis1 [u] -dis1 [lca (u, v)] + dis2 [v] -dis2 [lca (u, v)]
#include<bits/stdc++.h> using namespace std; #define mst(ss,b) memset((ss),(b),sizeof(ss)) const int N = 1e5+5; int t,n,m,dis[N],dis1[N],fa[N][20],fa1[N][20],dep[N],dep1[N],vs[N],vs1[N]; struct nd{ int to,w,w1; }; vector<nd> g[N]; void init() { for(int i=1;i<=n;i++) g[i].clear(); mst(dis,0),mst(fa,0),mst(dep,0), MST (VS, 0 ); MST (DIS1, 0 ), MST (FA1, 0 ), MST (Dep 1, 0 ), MST (VS1, 0 ); } void DFS ( int X) { /// obtained each node of the root node to the distance, depth, father VS [X] = . 1 ; for ( int I = 0 ; I <G [X] .size (); I ++ ) { Nd TP = G [X] [I] ; int V = tp.to, tp.w = W, W1 = tp.w1; IF (VS [V]) Continue ; FA [V] [ 0 ] = X; FA1 [V] [0 ] = X; DIS [V] = DIS [X] + W; DIS1 [V] = DIS1 [X] + W1; DEP [V] = DEP [X] + . 1 ; Dep 1 [V] = Dep 1 [X] + . 1 ; DFS (V); } } void BZ () { /// multiplication preprocessing for ( int J = . 1 ; J < 20 is ; J ++) /// FA [i] [J] denotes the node i 2 ^ j ancestor for ( int I = . 1 ; I <= n-; I ++ ) FA [I] [J] = FA [FA [I] [J- . 1 ]] [J- . 1], FA1 [I] [J] = FA1 [FA1 [I] [J- . 1 ]] [J- . 1 ]; } int LCA ( int U, int V) { IF (DEP [U] <DEP [V] ) the swap (u, V); /// Note exchange u and v, not exchange DEP [u] and DEP [V] int D = DEP [u] - DEP [V]; for ( int I = 0 ; I < 20 is ; I ++) /// first adjusted to the same depth IF (D & ( . 1 << I)) U = FA [U] [I]; IF (U == V) return U; for ( int I = . 19 ; i> =0 ; i--) { /// Note that for backwards is, binary split, descending attempts IF (FA [U] [I] =! FA [V] [I]) { U = FA [U ] [I]; V = FA [V] [I]; } } return FA [U] [ 0 ]; } int main () { the while (~ Scanf ( " % D " , & T)) { the while (T - ) { Scanf ( " % D " , & n-); the init (); Long Long ANS = 0 ; for(int i=1;i<n;i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); g[a].push_back({b,c,d}); g[b].push_back({a,d,c}); ans += c+d; } dep[1]=1,dis[1]=0; dep1[1]=1,dis1[1]=0; dfs(1); bz(); scanf("%d",&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); printf("%lld\n",ans-(dis1[v]-dis1[lca(u,v)]+dis[u]-dis[lca(u,v)])); } } } return 0; }