[POJ 1986] Distance Queries (LCA)

Source: Internet
Author: User

Distance QueriesLCA problem: LCA: Least Common Ancestors (recent Common ancestor). For any two nodes u and v with a root tree T, find the LCA (T, u, v ), that is, the farthest node x from the same end makes x both the ancestor of u and v.
Online algorithms: preprocessing is performed over a long period of time. However, when the information is sufficient, only a relatively small amount of time is required for each query.
Offline algorithms: read all the queries first, and then all the answers are completed together. The following blog provides an introduction to the LCA problem and the Tarjin and RMQ algorithms. Http://www.cppblog.com/Icyflame/archive/2009/07/04/88987.html

The Tarjin (offline algorithm) is an offline algorithm that obtains all queries and then processes them in a unified manner. It is implemented using DFS + and query sets. The Tarjan algorithm processes a node X in the following steps:
1. Create a set with only one X node. That is, in the query set, root [X] = X and mark that the node has been accessed.
2. process all queries about X. For (X, Y), if Y has been processed, then LCA (X, Y) = find (Y ), that is, Y is the root node in the query set. If Y has not been processed, ignore this query.
To process all the queries, you must add (X, Y) to the X and Y nodes respectively. 3. recursion this process processes X's children.
4. Set root [X] to father [X], that is, the father of X.
Pseudocode:

// Parent is the Union query set, and FIND is the Union query operation 2 Tarjan (u) 3 visit [u] = true 4 for each (u, v) in QUERY 5 if visit [v] 6 ans (u, v) = FIND (v) 7 for each (u, v) in TREE 8 if! Visit [v] 9 Tarjan (v) 10 parent [v] = u
The following blog gives a clear explanation of the Tarjin algorithm. Http://hi.baidu.com/billdu/item/9938ed34ab9416352e20c41f

The DFS + RMQ (online algorithm) LCA algorithm can be converted to the RMQ algorithm: (1) DFS: Performs depth-first traversal starting from the root of the tree T, and records the vertices that arrive at each time. The first node is root (T), and each edge records its endpoint. Because each edge exactly goes through two times, a total of 2n-1 nodes are recorded, expressed by E [1,..., 2n-1. In the DFS process, the depth of each vertex is recorded at the same time. Use depth [] to record. In the DFS process, record the array subscript that reaches the vertex for the first time.
(2) calculate R: Use R [I] to represent the subscript of the element whose first value is I in the E array. That is, if R [u] <R [v, the DFS access sequence is E [R [u], R [u] + 1 ,..., R [v]. Although it contains the descendant of u, but the smallest depth is the common ancestor of u and v.
(3) RMQ: When R [u] ≥r [v], LCA [T, u, v] = RMQ (L, R [v], R [u]); otherwise, LCA [T, u, v] = RMQ (L, R [u], R [v]) calculates RMQ.
Because the ST Algorithm Used in RMQ is an online algorithm, this algorithm is also an online algorithm.
Http://www.cnblogs.com/scau20110726/archive/2013/05/26/3100812.html
Http://dongxicheng.org/structure/lca-rmq/


Calculate the shortest distance between two nodes (u, v) in a tree, and use LCA to retrieve the root of the nearest common ancestor. The shortest distance is dis [u] + dis [v]-2 * dis [root]. Dis indicates the distance from each node to the root node.
Tarjin algorithm:
/* Tarjin offline algorithm struct node {int x, d ;}; int n, m, dis [maxn], ans [maxn], vis [maxn] = {0 }, f [maxn]; vector
 
  
V [maxn], query [maxn]; void init () {scanf ("% d", & n, & m); int a, B; char ch; node tmp; for (int I = 0; I <m; I ++) {scanf ("% d % c", & a, & B, & tmp. d, & ch); tmp. x = B; V [a]. push_back (tmp); tmp. x = a; V [B]. push_back (tmp);} scanf ("% d", & m); for (int I = 0; I <m; I ++) {scanf ("% d", & a, & B); tmp. d = I, tmp. x = B; query [a]. push_back (tmp); tmp. x = a; query [B]. push_back (tmp) ;}} int find (int x) {if (f [X]! = X) f [x] = find (f [x]); return f [x];} void dfs (int u, int d) {vis [u] = 1, f [u] = u, dis [u] = d; for (int I = 0; I <query [u]. size (); I ++) if (vis [query [u] [I]. x]) {int v = query [u] [I]. x, w = query [u] [I]. d; ans [w] = dis [u] + dis [v]-2 * dis [find (v)];} for (int I = 0; I <V [u]. size (); I ++) if (! Vis [V [u] [I]. x]) {int v = V [u] [I]. x, w = V [u] [I]. d; dfs (v, d + w); f [v] = u ;}} int main () {init (); dfs (1, 0 ); for (int I = 0; I <m; I ++) printf ("% d \ n", ans [I]); return 0 ;}*/
 


DFS + RMQ algorithm:
// DFS + RMQ online algorithm struct node {int x, d ;}; vector
 
  
V [maxn]; int E [maxn * 2], D [maxn * 2], first [maxn], vis [maxn], dis [maxn], n, m, top = 1; int dp [30] [maxn * 2]; void init () {scanf ("% d", & n, & m); int, b; char ch; node tmp; for (int I = 0; I <m; I ++) {scanf ("% d % c", &, & B, & tmp. d, & ch); tmp. x = B; V [a]. push_back (tmp); tmp. x = a; V [B]. push_back (tmp) ;}} void dfs (int u, int dep, int w) {vis [u] = 1, E [top] = u, D [top] = dep, first [u] = top ++, di S [u] = w; for (int I = 0; I <V [u]. size (); I ++) if (! Vis [V [u] [I]. x]) {int v = V [u] [I]. x, cost = V [u] [I]. d; dfs (v, dep + 1, w + cost); E [top] = u, D [top ++] = dep ;}} void ST (int num) {for (int I = 1; I <= num; I ++) dp [0] [I] = I; for (int I = 1; I <= log2 (num); I ++) for (int j = 1; j <= num; j ++) if (j + (1 <I) -1 <= num) {int a = dp [I-1] [j], B = dp [I-1] [j + (1 <I> 1)]; if (D [a] <D [B]) dp [I] [j] = a; else dp [I] [j] = B;} int RMQ (int x, int y) {int k = (int) log2 (y-x + 1.0); int a = dp [k] [x], B = dp [k] [y-(1 <k) + 1]; if (D [a] <D [B]) return a; return B;} int main () {init (); dfs (1, 0, 0 ); ST (top-1); scanf ("% d", & m); int x, y; while (m --) {scanf ("% d ", & x, & y); int a = first [x], B = first [y]; if (a> B) swap (a, B ); int pos = RMQ (a, B); printf ("% d \ n ", dis [x] + dis [y]-2 * dis [E [pos]);} 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.