The basic idea and algorithm of the Tarjan (off-line) algorithm for the recent common ancestor of LCA ad: METO CODE Anxi One in the online Informatics evaluation System (OJ)
Since this is the first blog post. A bit of a flaw ... For example, I write false flase ... Look at the time to pay attention!
And also... This word is more miscellaneous .... After all, it's the first time. There will be a change in the back!!!
The first is the concept of the recent public ancestor (what is the recent public ancestor?). ):
on a tree without a ring, each node must have its father and ancestor nodes, The most recent public ancestor, the two nodes in this tree, is the largest public ancestor node in depth .
In other words, it is the nearest common ancestor node of two points on this tree.
So LCA is mainly used to deal with the path when two points have only one determined shortest path.
One might ask: can he or his father node be the ancestor node?
The answer is yes, very simple, according to the concept of people's relatives, your father is also your ancestors , and LCA can also be seen as an ancestor node .
For example, as shown in 4 and 5 , the nearest public ancestor is 2,5 and 3 of the nearest public ancestor is 1,2 and the recent public ancestor of 1 is 1.
This is the basic concept of the recent public ancestor, so how do we seek this recent public ancestor?
Usually beginners will think of the simplest and most brutal way: For each query, traverse all points, time complexity is O (n*q), it is obvious thatN and q is generally not very small .
The commonly used algorithms for LCA are: tarjan/dfs+st/multiplication
The latter two algorithms are both online and very similar, with time complexity between O (logn)~o (nlogn) , which I personally think is more difficult to understand.
Some of the topics can be done with line tree, but its code is very large, time complexity is also high, in O (n) ~o (NLOGN) , the advantage is also simple rough .
This blog is mainly to introduce the Tarjan algorithm (in fact, I will not be online ...).
What is the Tarjan (offline) algorithm? As the name implies, all queries are resolved once in a single traversal, so their time complexity is O (n+q).
The advantage of the Tarjan algorithm is that it is relatively stable, the time complexity is also more centered, and it is easy to understand.
The following is a detailed introduction to the basic idea of the Tarjan algorithm:
1. Choose a point as the root node, starting at the root node.
2. Traverse the point u all child nodes V, and mark those child nodes V has been visited.
3. If v has a child node, return 2, or the next step.
4. Merge V to U.
5. Look for the point V with the current point you have a query relationship.
6. If V has been visited, then you can confirm that the nearest common ancestor of U and V is the Father Node A that V was merged into.
The traversal will need to use Dfs to traverse (I believe the people who see it), as for the merger, the most optimal way is to use and check the set to merge two nodes.
The following pseudo-code:
1Tarjan (U)//Marge and find for and look up merge functions and lookup functions2 {3 foreach (U,V)//access to all U-sub-nodes v4 {5Tarjan (v);//continue traversing down 6Marge (u,v);//Merge V to u on 7 Mark V has been visited; 8 }9 foreach (u,e)//access all and you have inquiry relationship e Ten { One If E has been visited; A the nearest public ancestor of U,e is find (e); - } -}
Personal feeling this is still a lot of people do not understand, so I intend to simulate it for everyone to see.
It is recommended to follow my description with paper and pen to simulate!!
Let's say we have a set of data 9 nodes with 8 edge connectivity as follows:
1--2,1--3,2--4,2--5,3--6, 5--7,5--8,7--9 the tree shown
We are going to find the point of the nearest public ancestor for 9--8,4--6,7--5,5--3;
Set f[] array as the parent node array of the set, initialize the f[i]=i,vis[] array as the array to be accessed, initially 0;
The following begins the simulation process:
Take 1 for root node , search down to find there are two sons 2 and 3;
Search first 2, found that 2 have two sons 4 and 5, first search 4, found that 4 has No child nodes , then look for their relationship with the point;
Found 6 and 4 have a relationship, but vis[6]=0, that is, 6 has not been searched, so do not operate ;
Found no and 4 have questioned the point of the relationship, return to the previous search, update vis[4]=1;
said 4 has been searched, update f[4]=2, continue to search 5, found 5 have two sons 7 and 8;
Search first 7, found that 7 has a child node 9, Search 9, found no child nodes, looking for their relationship with the point;
found that 8 and 9 have a relationship, but vis[8]=0, that is, 8 has not been searched, so do not operate;
Found no and 9 have questioned the point of the relationship, return to the previous search, update vis[9]=1;
said 9 has been searched, updated f[9]=7, found that 7 have not been searched sub-node, looking for its relationship with the point;
found that 5 and 7 have a relationship, but vis[5]=0, so do not operate ;
Found that there is no relationship with 7 points, return to the previous search, update vis[7]=1;
said 7 has been searched, update f[7]=5, continue to search 8, found that 8 No child nodes, then look for their relationship with the point;
Discovery 9 has a relationship with 8, at this time Vis[9]=1, then their recent public ancestor for find (9) =5;
(The Order of Find (9) is f[9]=7-->f[7]=5-->f[5]=5 return 5;)
Found no relationship with 8 points, return to the previous search, update vis[8]=1;
said 8 has been searched, updated f[8]=5, found 5 have not searched the sub-node, looking for its relationship with the point;
found that 7 and 5 had a relationship, at this time vis[7]=1, so their recent public ancestor for find (7) =5;
(The Order of Find (7) is f[7]=5-->f[5]=5 return 5;)
Also found that 5 and 3 have a relationship, but vis[3]=0, so do not operate , at this time 5 of the child nodes are all searched;
Return to the previous search, update vis[5]=1, indicating that 5 has been searched, updated f[5]=2;
found that 2 have not been searched for the sub-node, looking for its relationship with the point;
Also found that there is no relationship with 2 points, the previous search, update vis[2]=1;
said 2 has been searched, update f[2]=1, continue to search 3, found that 3 has a child node 6;
Searching for 6, found that 6 had no child nodes, then looked for 6 related points, found 4 and 6 have a relationship;
at this time vis[4]=1, so their nearest public ancestor is find (4) =1;
(The Order of Find (4) is f[4]=2-->f[2]=2-->f[1]=1 return 1;)
Found that there is no relationship with 6 points, return to the previous search, update vis[6]=1, indicating that 6 has been searched;
update f[6]=3, found that 3 have not been searched sub-node, then look for the point with 3 relations;
found that 5 and 3 have a relationship, at this time Vis[5]=1, then their nearest public ancestor is find (5) =1;
(The Order of Find (5) is f[5]=2-->f[2]=1-->f[1]=1 return 1;)
Found that there is no relationship with 3 points, return to the previous search, update vis[3]=1;
update F[3]=1, found 1 No searched child nodes also have no relationship point, at this time can exit the entire DFS .
after this DFS we are have you got all the answers, do you think it's magical? Is there a deeper understanding of the Tarjan algorithm?
If you do not understand can be in the following message to ask or send a question to [email protected].
Recommended several LCA topics
Codevs 2370 Tree portal for small room
CODEVS 1036 Business Travel Portal
METO CODE 223 Rally Portal
HDU 2586 how far? Portal
ZOJ 3195 Design the city portal
The corresponding puzzle may be in the future, we kindly hope.
Recent public ancestor LCA (Tarjan algorithm) thinking and algorithm implementation--reprinted from Vendetta Blogs