Principle Explanation: http://dongxicheng.org/structure/lca-rmq/
Online algorithm templates:
/**LCA online algorithm O (NLOGN) main function call: Init (); Tot=0,dir[1]=0;dfs (n); ST (2*n-1); int Lca=lca (U,V); * * #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <math.h>using namespace Std;const int maxn=40010;///node number const int Maxm=25;int _POW[MAXM ],m,n;///preprocessing 2 of the power int head[maxn],ip;int ver[maxn*2],r[maxn*2],first[maxn],dir[maxn],dp[maxn*2][maxm],tot;/// The array in turn represents the node storage for the U position, the X-position node depth store, the first access time, the distance to the root node, the RNQ array, and the tot point in turn, which accesses the tag bool vis[maxn];void init () {memset (vis,false,sizeof ( VIS)); memset (head,-1,sizeof (head)); Ip=0;} struct note{int v,w,next;} Edge[maxn*2];void addedge (int u,int v,int W) {edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;} void Dfs (int u,int dep) {vis[u]=true; VER[++TOT]=U,FIRST[U]=TOT,R[TOT]=DEP; for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v; int W=EDGE[I].W; if (!vis[v]) {dir[v]=dir[u]+w; DFS (V,DEP+1); VER[++TOT]=U,R[TOT]=DEP; } }}void ST (int len)///RMQ preprocessing {int k= (int) log ((double) len)/(log (2.0)); for (int i=1;i<=len;i++) {dp[i][0]=i; } for (int j=1;j<=k;j++) {for (int i=1;i+_pow[j]-1<=len;i++) {int a=dp[i][j-1],b=dp[i +_POW[J-1]][J-1]; if (r[a]<r[b]) dp[i][j]=a; else dp[i][j]=b; }}}int RMQ (int x,int y)///query {int k= (int) log ((double) (y-x+1)/log (2.0)); int a=dp[x][k],b=dp[y-_pow[k]+1][k]; if (R[a]<r[b]) return A; else return b;} int LCA (int u,int v)///lca, the return value is u,v lca{int x=first[u],y=first[v]; if (x>y) swap (x, y); int res=rmq (x, y); return ver[res];}
Offline Solution:
/**LCA (offline algorithm) The main function should also call init ();d Ir[1]=0;tarjan (1) In addition to the build edge; */#include <stdio.h> #include <string.h> #include < Iostream> #include <algorithm>using namespace std;const int maxn=40010;struct note{int u,v,w,lca,next;} Edge[maxn*2],edge1[805];int head[maxn],ip,head1[maxn],ip1;///needs to be built two times. 1, the edge of the tree 2, you need to query the two point int m,n;int father[maxn],vis[maxn],dir[maxn];///in turn indicates the ancestor of the U point, whether the tag has been accessed, the distance to the root node void init () {memset (vis,0, sizeof (VIS)); memset (Dir,0,sizeof (dir)); memset (head,-1,sizeof (head)); memset (head1,-1,sizeof (HEAD1)); ip=ip1=0;} void Addedge (int u,int v,int W) {edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;} void Addedge1 (int u,int v) {edge1[ip1].u=u,edge1[ip1].v=v,edge1[ip1].lca=-1,edge1[ip1].next=head1[u],head1[u]=ip1+ +;} int Find (int x) {if (father[x]==x) return x; Return Father[x]=find (Father[x]);} void Union (int x,int y) {x=find (x); Y=find (y); if (x!=y) father[y]=x;} void Tarjan (int u) {vis[u]=1; Father[u]=u; for (int i=head[U];i!=-1;i=edge[i].next) {int v=edge[i].v; int W=EDGE[I].W; if (!vis[v]) {dir[v]=dir[u]+w; Tarjan (v); Union (U,V); }} for (int i=head1[u];i!=-1;i=edge1[i].next) {int v=edge1[i].v; if (Vis[v]) {Edge1[i].lca=edge1[i^1].lca=father[find (v)]; } }}
LCA recent public ancestor online algorithms and offline algorithm templates