Recent public ancestor LCA Tarjan algorithm

Source: Internet
Author: User

From: http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html

For a tree with a root, there will be a Father node, ancestor node, of course, the recent public ancestor is the two points in all the ancestor nodes of the deepest node.

0

|

1

/   \

2 3

Here, for example, if 0 is the root, then 1 is the Father node of 2 and 3, 0 is the Father node of 1, 0 and 1 are common ancestor nodes of 2 and 3, but 1 is the nearest common ancestor node, or 1 is the ancestor node farthest from the root node in all ancestor nodes of 2 and 3.

In solving the problem of the recent public ancestor, using the idea of Tarjan, starting from the root node to form a deep search tree, very good processing technique is to go back to the node U, the subtree of U has been traversed, this time the U node into the merge set, So the nearest common ancestor of the nodes in the U-node and all the subtree of U is u, and the nearest public ancestor of all U's sibling nodes and subtrees that you have not traversed is the Father node of U. etc... In this way we are naturally dividing the nodes in the tree into a number of sets when we traverse the depth of the tree, and the common ancestor of any pair of vertices belonging to the different sets in the two collection is the same, that is, the nearest public of the two collections is first only one. For each set can be used and check the set to optimize, time complexity is greatly reduced, for O (n + q), n is the sum of points, Q is the logarithm of the query node.

Another Tarjan solution, is an off-line algorithm, that is, it must be all the inquiry first recorded, and once again to find out each point pair of the recent public ancestors, only in this way can be achieved to reduce the complexity of time. There is also an online algorithm that needs to be learned.

Pseudo code:

Parent for the and check set, find for and look up the set of operations
Query for the query node pair collection
Tree as base map with root trees
Tarjan (U)
Visit[u] = True
For each (U, v) in QUERY
If VISIT[V]
Ans (u, v) = FIND (v)
For each (U, v) in TREE
If!VISIT[V]
Tarjan (v)
PARENT[V] = u

Classic examples:

hdu2586 How far away?

This problem test instructions is, given a tree, each side has a certain weight, q times asked, each time asked about the distance between two points. So you can use LCA to solve, first find the U, v two point of the LCA, and then calculate the distance value on it. Here the calculation method is, note the root node to any point of distance dis[], so that ans = dis[u] + dis[v]-2 * DIS[LCA (V, v)], this expression is relatively easy to understand:

//============================================================================//Name:hdu2586.cpp//Author:birdfly//Description: Recent public ancestor//============================================================================#include<iostream>#include<string.h>#include<stdio.h>#defineNN 40002// Number of house#defineMM 202//Number of queryusing namespaceStd;typedefstructnode{intv; intD; structNode *NXT;} NODE; NODE*Link1[nn]; NODE Edg1[nn*2];//the edges in the treeNODE*Link2[nn]; NODE Edg2[nn*2];//the point of Inquiryintidx1, IDX2, N, M;intres[mm][3];//recording results, res[i][0]: u res[i][1]: v res[i][2]: LCA (U, v)intFat[nn];intVis[nn];intDis[nn];voidADD (intUintVintd, node edg[], node *link[],int&idx) {EDG[IDX].V=v; EDG[IDX].D=D; EDG[IDX].NXT=Link[u]; Link[u]= EDG + idx++; EDG[IDX].V=u; EDG[IDX].D=D; EDG[IDX].NXT=Link[v]; LINK[V]= EDG + idx++;}intFindintx) {//and check set path compression    if(X! =Fat[x]) {        returnFAT[X] =find (fat[x]); }    returnx;}voidTarjan (intu) {Vis[u]=1; Fat[u]=u;  for(NODE *p = link2[u]; p; p = p->NXT) {        if(vis[p->v]) {Res[p->d][2] = find (P-&GT;V);//is the closest common ancestor node .        }    }     for(NODE *p = link1[u]; p; p = p->NXT) {        if(!vis[p->v]) {Dis[p-&GT;V] = Dis[u] + p->D; Tarjan (P-v); Fat[p-&GT;V] =u; }    }}intMain () {intT, I, U, V, D; scanf ("%d", &u);  while(t--) {scanf ("%d%d", &n, &M); Idx1=0; memset (LINK1,0,sizeof(LINK1));  for(i =1; i < N; i++) {scanf ("%d%d%d", &u, &v, &d);        ADD (U, V, D, EDG1, Link1, idx1); } idx2=0; memset (LINK2,0,sizeof(LINK2));  for(i =1; I <= M; i++) {scanf ("%d%d", &u, &v);            ADD (U, V, I, EDG2, Link2, IDX2); res[i][0] =u; res[i][1] =v; } memset (Vis,0,sizeof(VIS)); dis[1] =0; Tarjan (1);  for(i =1; I <= M; i++) {printf ("%d\n", dis[res[i][0]] + dis[res[i][1]] -2* dis[res[i][2]]); }    }    return 0;}

Recent public ancestor LCA Tarjan algorithm

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.