/*
Minimum common ancestor
Question: Give an undirected right tree and ask for the distance between several (u, v) pairs.
The so-called LCA Tarjan algorithm is actually to calculate the LCA in the query During the creation process, so it is called the 'offline algorithmic '. yes, the essence is so simple that many interpretations are complicated.
Steps: Google.
To understand this algorithm, we must grasp the 'recursion 'idea (there are also recursion in it, and we must also grasp it ).
Tarjan uses and queries the set. In the recursive process, the root node of a tree represents the tree (contact and query the set). The benefit of doing so is that, if you ask me about the LCA of I and J, we only need to find the smallest subtree of I and J, because this subtree is our answer. how can we determine the subtree? This will be explained later.
Next we will talk about Tarjan's most clever points. because all queries are calculated during the build process, it indicates whether we can calculate a query pair (u, v) at the moment. The condition is: whether u and v have been traversed. therefore, we can calculate the query when traversing to V (assuming the time after V is later than U. for example, lcm (u, v) is find (u ). what if the find (V) and LCM (u, v) at the moment are not equal? The answer is not equal, at least in the implementation of my code. because the update of Father [x] is updated when 'recursive return', but at the moment it is traversing vertices and hasn't been recursively rolled back yet, father [v] is not updated.
In fact, the previous section has already answered the question 'How to determine which subtree is the answer we want? ', that is, the subtree represented by find (u! Note that it is find (u), not find (v )! Because U has been traversed before V, and it has been recursively returned to sub_root, that is, Father [u] has been updated to sub_root, so find (u) it can represent the current sub_tree, that is, 'minimum contain (u, v) subtree'
Let's look at the two explanations below, and I recommend that you read the code to make it easier to understand.
Http://www.nocow.cn/index.php/Tarjan%E7% AE %97%E6%B3%95
Http://blog.chinaunix.net/uid-1721137-id-181005.html
*/
# Include <vector>
# Include <stdio. h>
Using namespace STD;
# Define maxn40001
# Define debug printf ("! \ N ")
Vector <int> V [maxn], W [maxn], Query [maxn], ans_num [maxn];
Int father [maxn], DIS [maxn], ANS [201];
Bool visit [maxn];
Int N;
Void Init ()
{
For (INT I = 1; I <= N; I ++ ){
V [I]. Clear ();
W [I]. Clear ();
Ans_num [I]. Clear ();
Query [I]. Clear ();
Father [I] = I;
Dis [I] = 0;
Visit [I] = false;
}
}
Int find (int x)
{
Return x = Father [x]? X: Father [x] = find (father [x]);
}
Void Union (int x, int y) {FATHER [find (y)] = find (x );}
Void Tarjan (INT now, int value)
{
Visit [now] = true;
Dis [now] = value;
For (INT size = V [now]. Size (), I = 0; I <size; I ++ ){
Int TMP = V [now] [I];
If (visit [TMP]! = 0) continue;
Tarjan (TMP, value + W [now] [I]);
Union (now, TMP); // pay attention to the sequence. First, the Tarjan sub-node TMP is updated, and then its father [TMP] is updated, because when the sub-tree represented by TMP is recursive, father [TMP] = TMP, which is irrelevant to the current subtree. after recursion, merge the child Tree represented by TMP into the current tree.
}
For (INT size = Query [now]. Size (), I = 0; I <size; I ++ ){
Int TMP = Query [now] [I];
If (! Visit [TMP]) continue; // If visit [TMP] = true, it indicates that the TMP node has been traversed and the corresponding query can be calculated
Ans [ans_num [now] [I] = dis [now] + dis [TMP]-2 * Dis [find (TMP)];
}
}
Int main ()
{
INT cases, query, x, y, z;
Scanf ("% d", & cases );
While (cases --){
Scanf ("% d", & N, & query );
Init ();
For (INT I = 1; I <n; I ++ ){
Scanf ("% d", & X, & Y, & Z );
V [X]. push_back (y );
W [X]. push_back (z );
V [Y]. push_back (X );
W [Y]. push_back (z );
}
For (INT I = 0; I <query; I ++ ){
Scanf ("% d", & X, & Y );
Query [X]. push_back (y );
Query [Y]. push_back (X );
Ans_num [X]. push_back (I );
Ans_num [Y]. push_back (I );
}
Tarjan (1, 0 );
For (INT I = 0; I <query; I ++) printf ("% d \ n", ANS [I]);
}
Return 0;
}