(Algorithm) The Tarjan offline algorithm solves the LCA problem (with the poj 1470 closest common ancestors code)

Source: Internet
Author: User

For the recent public ancestor problem, let's first look at this nature. When the recent public ancestor of the two nodes (u, v) is X, then we can be sure to say, when performing post-order traversal, you must first access all the child trees of X before returning to the node where X is located. This is the core idea of using the Tarjan algorithm to solve recent common ancestor problems.

At the same time, how can we ensure that this is the recent public ancestor? In this way, because we gradually backtrack data, each time we access a subtree of node X, we put all the nodes in the subtree into the set where node X is located, and we set the ancestor of all elements in this set to the node X. Then, when we access all the sub-trees of a node, we mark the node as the point where the ancestor has been found.

At this time, Tarjan adopts the offline method to solve the problem of the recent public ancestor, so this is the case. Assume that the node We just accessed is A, so let's see if B has been accessed at another point we asked together. If B has already been accessed, at this time, the recent public ancestor must be the C ancestor of the collection where B is located, because our access to a is transferred from the recent public ancestor C, in addition, when we switched from the subtree B of C to A, we have set the ancestor of B to C. At the same time, C is also the ancestor of, C must be the recent common ancestor of A and B.

For all nodes in a subtree, the ancestor is the root node of the subtree. Therefore, we often need to update the ancestor of the entire subtree during backtracking. To facilitate processing, we use and query sets to maintain the ancestor of a set. The total time complexity is O (n + q), because DFS is O (n), and then the query is probably O (q.

This is the offline Tarjan algorithm. It may be hard to say clearly, but it is easy to write. The following is the code of the question I have posted on poj 1470. It is a simple solution to the LCA problem.

/*author UESTC_Nowitzki */#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>using namespace std;const int MAX=1000;int indegree[MAX];int ancestor[MAX];int set[MAX];int vis[MAX];int time[MAX];vector<int> adj[MAX];vector<int> que[MAX];void init(int n){    memset(time,0,sizeof(time));    memset(vis,0,sizeof(vis));    memset(indegree,0,sizeof(indegree));    for(int i=1;i<=n;i++)    {        adj[i].clear();        que[i].clear();        set[i]=i;        ancestor[i]=i;    }}int find(int k){    int r=k;    while(set[r]!=r)        r=set[r];    int i=k,j;    while(set[i]!=r)    {        j=set[i];        set[i]=r;        i=j;    }    return r;}void dfs(int i){    int len=adj[i].size();    for(int j=0;j<len;j++)    {        int son=adj[i][j];        dfs(son);        set[son]=i;        ancestor[find(i)]=i;    }    vis[i]=1;    len=que[i].size();    for(int j=0;j<len;j++)    {        int son=que[i][j];        if(vis[son])        {            int ans=ancestor[find(son)];            time[ans]++;        }    }}int main(){    int n,i,t,a,b;    while(scanf("%d",&n)!=EOF)    {        init(n);        for(i=0;i<n;i++)        {            scanf("%d:(%d)",&a,&t);            while(t--)            {                scanf("%d",&b);                indegree[b]++;                adj[a].push_back(b);            }        }        scanf("%d",&t);        while(t--)        {            while(getchar()!='(');            scanf("%d%d",&a,&b);            que[a].push_back(b);            que[b].push_back(a);        }        while(getchar()!=')');        for(i=1;i<=n;i++)        {            if(indegree[i]==0)            {  //              printf("root=%d\n",i);                dfs(i);                break;            }        }        for(i=1;i<=n;i++)        {            if(time[i]>0)                printf("%d:%d\n",i,time[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.