# Python3 implementation of the above approach
import math
# Pre-processing to calculate values of memo[][]
def dfs(u, p, memo, lev, log, g):
# Using recursion formula to calculate
# the values of memo[][]
memo[u][0] = p
for i in range(1, log + 1):
memo[u][i] = memo[memo[u][i - 1]][i - 1]
for v in g[u]:
if v != p:
lev[v] = lev[u] + 1
dfs(v, u, memo, lev, log, g)
# Function to return the LCA of nodes u and v
def lca(u, v, log, lev, memo):
# The node which is present farthest
# from the root node is taken as u
# If v is farther from root node
# then swap the two
if lev[u] < lev[v]:
swap(u, v)
# Finding the ancestor of u
# which is at same level as v
for i in range(log, -1, -1):
if (lev[u] - pow(2, i)) >= lev[v]:
u = memo[u][i]
# If v is the ancestor of u
# then v is the LCA of u and v
if u == v:
return v
# Finding the node closest to the
# root which is not the common ancestor
# of u and v i.e. a node x such that x
# is not the common ancestor of u
# and v but memo[x][0] is
for i in range(log, -1, -1):
if memo[u][i] != memo[v][i]:
u = memo[u][i]
v = memo[v][i]
# Returning the first ancestor
# of above found node
return memo[u][0]
# Driver code
# Number of nodes
n = 9
log = math.ceil(math.log(n, 2))
g = [[] for i in range(n + 1)]
memo = [[-1 for i in range(log + 1)]
for j in range(n + 1)]
# Stores the level of each node
lev = [0 for i in range(n + 1)]
# Add edges
g[1].append(2)
g[2].append(1)
g[1].append(3)
g[3].append(1)
g[1].append(4)
g[4].append(1)
g[2].append(5)
g[5].append(2)
g[3].append(6)
g[6].append(3)
g[3].append(7)
g[7].append(3)
g[3].append(8)
g[8].append(3)
g[4].append(9)
g[9].append(4)
dfs(1, 1, memo, lev, log, g)
print("The LCA of 6 and 9 is", lca(6, 9, log, lev, memo))
print("The LCA of 5 and 9 is", lca(5, 9, log, lev, memo))
print("The LCA of 6 and 8 is", lca(6, 8, log, lev, memo))
print("The LCA of 6 and 1 is", lca(6, 1, log, lev, memo))
# This code is contributed by Bhaskar