ST--LCA Online algorithm
"LCA Exercise" recent public ancestor (version 1)
Description
Give you a tree that asks you to calculate the nearest public ancestor of M-to-node.
Input
The first line of the input file contains two integers n and m (2<=n,m<=200,000), where n is the number of nodes, and the node number 1 to n;m indicates the number of queries.
Next n-1 line, two integers x and y per line, indicates that node x is the Father node of node y;
The next M-line, two integers a and b per line, requires that the nearest public ancestor of nodes A and b be computed.
Output
The output file is a total of M rows, respectively, the nearest common ancestor number for each pair of nodes.
Sample Input
5 3
2 3
3 4
3 1
1 5
3 5
4 5
1 2
Sample Output 3
3
2
Thought:
Conversion to RMQ-like problems to solve
Algorithm steps:
- Read in
- Find out the depth of each node
- Open an array p[i][k] indicates which node the ancestor of the K-th party from the I-node upward 2
- Initialize, dynamic programming to find out P[i][k]
- Solve each pair of problems online, leveling the A and B nodes, decreasing upward by the maximum k, until a node above A and B is a common ancestor
Pseudo code:
#include <bits/stdc++.h>using namespacestd;structforward star {}a[100000]; inth[300000];intCNT;intn,m;intprt[300000];intRoot;intd[300000];intp[300000][ -];voidUnion (intXinty) {Connect x, y nodes}voidGetdeep (intv0,deep) {Recursively find the depth of each node from the root node}intDealintXintY//On- Line St algorithm{ 1. Make d[x]>D[y], easy to operate2Find the largest k (max upward expansion height <=2 k-th square)3. Leveling the X, y node4. Special Award5. In descending order of K, X, y simultaneously climbs, if ... 6. Return to P[x][0]; } intMain () {CIN>>n>>m; Loop read-in finding root node recursion depth*Initialize DP to find out P[I][K]; On-line solution for each pair of questions}
It's time to press yajing with real code.
#include <bits/stdc++.h>using namespacestd;structeg{intNext,to;} a[300000];inth[300000];intCNT;intn,m;intprt[300000];intRoot;intd[300000];intp[300000][ -];voidUnion (intXinty) {CNT++; A[cnt].to=y; A[cnt].next=H[x]; H[X]=CNT;}voidGetdeep (intV0,intDeep ) {D[v0]=Deep ; for(intI=h[v0];i;i=A[i].next) {Getdeep (A[i].to,deep+1); }}intDealintXinty) { if(d[x]<D[y]) swap (x, y); intKey=log (D[x])/log (2); for(inti=key;i>=0; i--) { if(D[x]-(1<<i) >=d[y]) x=P[x][i]; } if(x==y)returny; for(inti=key;i>=0; i--) { if(P[x][i]!=p[y][i]) x=p[x][i],y=P[y][i]; } returnp[x][0];}intMain () {Ios::sync_with_stdio (false); CIN>>n>>m; for(intI=1; i<=n-1; i++) { intTis,tit; scanf ("%d%d",&tis,&tit); Union (Tis,tit); Prt[tit]=tis; } introot=1; while(Prt[root]) root=Prt[root]; Getdeep (Root,1); for(intI=1; i<=n;i++) {p[i][0]=Prt[i]; } for(intk=1;(1<<K) <=n;k++) { for(intI=1; i<=n;i++) {P[i][k]=p[p[i][k-1]][k-1]; } } for(intI=1; i<=m;i++) { intTis,tit; scanf ("%d%d",&tis,&tit); printf ("%d\n", Deal (Tis,tit)); }}
ST--LCA Online algorithm