# Lowest Common Ancestor for a Set of Nodes in a Rooted Tree

Given a rooted tree with **N** nodes, the task is to find the **Lowest Common Ancestor** for a given set of nodes **V** of that tree.

**Examples:**

Input:1 / | \ 2 3 4 / \ | | 5 6 7 10 / \ 8 9 V[] = {7, 3, 8, 9}Output:3Input:1 / | \ 2 3 4 / \ | | 5 6 7 10 / \ 8 9 V[] = {4, 6, 7}Output:1

**Approach:** We can observe that

- the Lowest Common Ancestors for any set of nodes will have in-time less than or equal to that of all nodes in the set and out-time greater than or equal(equal if LCA is present in the set) to that of all nodes in the set.
- Thus, in order to solve the problem, we need to traverse the entire tree starting from the root node using Depth First Search Traversal and store the in-time, out-time, and level for every node.
- The node with in-time less than or equal to all the nodes in the set and out-time greater than or equal to all the nodes in the set and with maximum level possible is the answer.

Below is the implementation of the above approach:

## C++

`// C++ Program to find the LCA ` `// in a rooted tree for a given ` `// set of nodes ` ` ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Set time 1 initially ` `int` `T = 1; ` `void` `dfs(` `int` `node, ` `int` `parent, ` ` ` `vector<` `int` `> g[], ` ` ` `int` `level[], ` `int` `t_in[], ` ` ` `int` `t_out[]) ` `{ ` ` ` ` ` `// Case for root node ` ` ` `if` `(parent == -1) { ` ` ` `level[node] = 1; ` ` ` `} ` ` ` `else` `{ ` ` ` `level[node] = level[parent] + 1; ` ` ` `} ` ` ` ` ` `// In-time for node ` ` ` `t_in[node] = T; ` ` ` `for` `(` `auto` `i : g[node]) { ` ` ` `if` `(i != parent) { ` ` ` `T++; ` ` ` `dfs(i, node, g, ` ` ` `level, t_in, t_out); ` ` ` `} ` ` ` `} ` ` ` `T++; ` ` ` ` ` `// Out-time for the node ` ` ` `t_out[node] = T; ` `} ` ` ` `int` `findLCA(` `int` `n, vector<` `int` `> g[], ` ` ` `vector<` `int` `> v) ` `{ ` ` ` ` ` `// level[i]--> Level of node i ` ` ` `int` `level[n + 1]; ` ` ` ` ` `// t_in[i]--> In-time of node i ` ` ` `int` `t_in[n + 1]; ` ` ` ` ` `// t_out[i]--> Out-time of node i ` ` ` `int` `t_out[n + 1]; ` ` ` ` ` `// Fill the level, in-time ` ` ` `// and out-time of all nodes ` ` ` `dfs(1, -1, g, ` ` ` `level, t_in, t_out); ` ` ` ` ` `int` `mint = INT_MAX, maxt = INT_MIN; ` ` ` `int` `minv = -1, maxv = -1; ` ` ` `for` `(` `auto` `i = v.begin(); i != v.end(); i++) { ` ` ` `// To find minimum in-time among ` ` ` `// all nodes in LCA set ` ` ` `if` `(t_in[*i] < mint) { ` ` ` `mint = t_in[*i]; ` ` ` `minv = *i; ` ` ` `} ` ` ` `// To find maximum in-time among ` ` ` `// all nodes in LCA set ` ` ` `if` `(t_out[*i] > maxt) { ` ` ` `maxt = t_out[*i]; ` ` ` `maxv = *i; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Node with same minimum ` ` ` `// and maximum out time ` ` ` `// is LCA for the set ` ` ` `if` `(minv == maxv) { ` ` ` `return` `minv; ` ` ` `} ` ` ` ` ` `// Take the minimum level as level of LCA ` ` ` `int` `lev = min(level[minv], level[maxv]); ` ` ` `int` `node, l = INT_MIN; ` ` ` `for` `(` `int` `i = 1; i <= n; i++) { ` ` ` `// If i-th node is at a higher level ` ` ` `// than that of the minimum among ` ` ` `// the nodes of the given set ` ` ` `if` `(level[i] > lev) ` ` ` `continue` `; ` ` ` ` ` `// Compare in-time, out-time ` ` ` `// and level of i-th node ` ` ` `// to the respective extremes ` ` ` `// among all nodes of the given set ` ` ` `if` `(t_in[i] <= mint ` ` ` `&& t_out[i] >= maxt ` ` ` `&& level[i] > l) { ` ` ` `node = i; ` ` ` `l = level[i]; ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `node; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `n = 10; ` ` ` `vector<` `int` `> g[n + 1]; ` ` ` `g[1].push_back(2); ` ` ` `g[2].push_back(1); ` ` ` `g[1].push_back(3); ` ` ` `g[3].push_back(1); ` ` ` `g[1].push_back(4); ` ` ` `g[4].push_back(1); ` ` ` `g[2].push_back(5); ` ` ` `g[5].push_back(2); ` ` ` `g[2].push_back(6); ` ` ` `g[6].push_back(2); ` ` ` `g[3].push_back(7); ` ` ` `g[7].push_back(3); ` ` ` `g[4].push_back(10); ` ` ` `g[10].push_back(4); ` ` ` `g[8].push_back(7); ` ` ` `g[7].push_back(8); ` ` ` `g[9].push_back(7); ` ` ` `g[7].push_back(9); ` ` ` ` ` `vector<` `int` `> v = { 7, 3, 8 }; ` ` ` ` ` `cout << findLCA(n, g, v) << endl; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

3

**Time Complexity:** *O(N)*

**Space Complexity:** *O(N)*

## Recommended Posts:

- Lowest Common Ancestor in a Binary Tree | Set 3 (Using RMQ)
- Lowest Common Ancestor in a Binary Tree | Set 1
- Lowest Common Ancestor in a Binary Search Tree.
- Lowest Common Ancestor in a Binary Tree | Set 2 (Using Parent Pointer)
- Least Common Ancestor of any number of nodes in Binary Tree
- Lowest Common Ancestor in Parent Array Representation
- Common nodes in the inorder sequence of a tree between given two nodes in O(1) space
- Tarjan's off-line lowest common ancestors algorithm
- Perform the given queries on the rooted tree
- Construct the Rooted tree by using start and finish time of its DFS traversal
- Print common nodes on path from root (or common ancestors)
- Minimum number of groups of nodes such that no ancestor is present in the same group
- Count the nodes of the tree which make a pangram when concatenated with the sub-tree nodes
- Construct tree from ancestor matrix
- K-th ancestor of a node in Binary Tree | Set 3
- K-th ancestor of a node in Binary Tree
- Kth ancestor of a node in binary tree | Set 2
- Query for ancestor-descendant relationship in a tree
- Construct Ancestor Matrix from a Given Binary Tree
- Construct Binary Tree from Ancestor Matrix | Top Down Approach

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.