HDU 2586 LCA

Source: Internet
Author: User
/*
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;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.