Lowest Common Ancestor for a Set of Nodes in a Rooted Tree | Python Program to find the LCA in a rooted tree for a given set of nodes ; Set time 1 initially ; Case for root node ; In - time for node ; Out - time for the node ; level [ i ] -- > Level of node i ; t_in [ i ] -- > In - time of node i ; t_out [ i ] -- > Out - time of node i ; Fill the level , in - time and out - time of all nodes ; To find minimum in - time among all nodes in LCA set ; To find maximum in - time among all nodes in LCA set ; Node with same minimum and maximum out time is LCA for the set ; Take the minimum level as level of LCA ; If i - th node is at a higher level than that of the minimum among the nodes of the given set ; Compare in - time , out - time and level of i - th node to the respective extremes among all nodes of the given set ; Driver code
from typing import List NEW_LINE from sys import maxsize NEW_LINE INT_MAX = maxsize NEW_LINE INT_MIN = - maxsize NEW_LINE T = 1 NEW_LINE def dfs ( node : int , parent : int , g : List [ List [ int ] ] , level : List [ int ] , t_in : List [ int ] , t_out : List [ int ] ) -> None : NEW_LINE INDENT global T NEW_LINE if ( parent == - 1 ) : NEW_LINE INDENT level [ node ] = 1 NEW_LINE DEDENT else : NEW_LINE INDENT level [ node ] = level [ parent ] + 1 NEW_LINE DEDENT t_in [ node ] = T NEW_LINE for i in g [ node ] : NEW_LINE INDENT if ( i != parent ) : NEW_LINE INDENT T += 1 NEW_LINE dfs ( i , node , g , level , t_in , t_out ) NEW_LINE DEDENT DEDENT T += 1 NEW_LINE t_out [ node ] = T NEW_LINE DEDENT def findLCA ( n : int , g : List [ List [ int ] ] , v : List [ int ] ) -> int : NEW_LINE INDENT level = [ 0 for _ in range ( n + 1 ) ] NEW_LINE t_in = [ 0 for _ in range ( n + 1 ) ] NEW_LINE t_out = [ 0 for _ in range ( n + 1 ) ] NEW_LINE dfs ( 1 , - 1 , g , level , t_in , t_out ) NEW_LINE mint = INT_MAX NEW_LINE maxt = INT_MIN NEW_LINE minv = - 1 NEW_LINE maxv = - 1 NEW_LINE for i in v : NEW_LINE INDENT if ( t_in [ i ] < mint ) : NEW_LINE INDENT mint = t_in [ i ] NEW_LINE minv = i NEW_LINE DEDENT if ( t_out [ i ] > maxt ) : NEW_LINE INDENT maxt = t_out [ i ] NEW_LINE maxv = i NEW_LINE DEDENT DEDENT if ( minv == maxv ) : NEW_LINE INDENT return minv NEW_LINE DEDENT lev = min ( level [ minv ] , level [ maxv ] ) NEW_LINE node = 0 NEW_LINE l = INT_MIN NEW_LINE for i in range ( n ) : NEW_LINE INDENT if ( level [ i ] > lev ) : NEW_LINE INDENT continue NEW_LINE DEDENT if ( t_in [ i ] <= mint and t_out [ i ] >= maxt and level [ i ] > l ) : NEW_LINE INDENT node = i NEW_LINE l = level [ i ] NEW_LINE DEDENT DEDENT return node NEW_LINE DEDENT if __name__ == " _ _ main _ _ " : NEW_LINE INDENT n = 10 NEW_LINE g = [ [ ] for _ in range ( n + 1 ) ] NEW_LINE g [ 1 ] . append ( 2 ) NEW_LINE g [ 2 ] . append ( 1 ) NEW_LINE g [ 1 ] . append ( 3 ) NEW_LINE g [ 3 ] . append ( 1 ) NEW_LINE g [ 1 ] . append ( 4 ) NEW_LINE g [ 4 ] . append ( 1 ) NEW_LINE g [ 2 ] . append ( 5 ) NEW_LINE g [ 5 ] . append ( 2 ) NEW_LINE g [ 2 ] . append ( 6 ) NEW_LINE g [ 6 ] . append ( 2 ) NEW_LINE g [ 3 ] . append ( 7 ) NEW_LINE g [ 7 ] . append ( 3 ) NEW_LINE g [ 4 ] . append ( 10 ) NEW_LINE g [ 10 ] . append ( 4 ) NEW_LINE g [ 8 ] . append ( 7 ) NEW_LINE g [ 7 ] . append ( 8 ) NEW_LINE g [ 9 ] . append ( 7 ) NEW_LINE g [ 7 ] . append ( 9 ) NEW_LINE v = [ 7 , 3 , 8 ] NEW_LINE print ( findLCA ( n , g , v ) ) NEW_LINE DEDENT