Open In App

Find triplet such that number of nodes connecting these triplets is maximum

Last Updated : 20 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a Tree with N nodes, the task is to find a triplet of nodes (a, b, c) such that the number of nodes covered in the path connecting these nodes is maximum. (Count a node only once).
Examples: 
 

Input: N = 4 
Edge Set: 
1 2 
1 3 
1 4 
Output: (2, 3, 4) 
(2, 3, 4) as path between (2, 3) covers nodes 2, 1, 3 and path between (3, 4) covers nodes 3, 1, 4. Hence all nodes are covered. 
 

The Red Path in Tree denotes the path between 2 to 3 node which covers node 1, 2, 3. The green path denotes path between (3, 4) which covers node 3, 1, 4.
Input: N = 9 
Edge Set : 
1 2 
2 3 
3 4 
4 5 
5 6 
2 7 
7 8 
4 9 
Output: (6, 8, 1) 
 

 

Approach: 
 

  • One important point to notice is, two of the points in triplet must be the end of diameter of tree to cover maximum of the points.
  • We need to find the longest length branch stick to the diameter.
  • Now for 3rd node, apply DFS along with maintaining the depth for each node (DFS in all directions other than on the Diameter Path Selected ) to all the nodes present on the path of Diameter, the node which is at the farthest distance, would be considered as the 3rd node, as it covers the maximum node other than already covered by the Diameter. Diameter of Tree using DFS

Below is the implementation of the above approach:
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
#define ll long long int
#define MAX 100005
using namespace std;
vector<int> adjacent[MAX];
bool visited[MAX];
 
// To store the required nodes
int startnode, endnode, thirdnode;
 
int maxi = -1, N;
 
// Parent array to retrace the nodes
int parent[MAX];
 
// Visited array to prevent DFS
// in direction on Diameter path
bool vis[MAX];
 
// DFS function to find the startnode
void dfs(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent[u].size(); i++) {
        if (!visited[adjacent[u][i]]) {
            temp++;
            dfs(adjacent[u][i], count + 1);
        }
    }
 
    if (temp == 0) {
        if (maxi < count) {
            maxi = count;
            startnode = u;
        }
    }
}
 
// DFS function to find the endnode
// of diameter and maintain the parent array
void dfs1(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent[u].size(); i++) {
        if (!visited[adjacent[u][i]]) {
            temp++;
            parent[adjacent[u][i]] = u;
            dfs1(adjacent[u][i], count + 1);
        }
    }
 
    if (temp == 0) {
        if (maxi < count) {
            maxi = count;
            endnode = u;
        }
    }
}
 
// DFS function to find the end node
// of the Longest Branch to Diameter
void dfs2(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent[u].size(); i++) {
        if (!visited[adjacent[u][i]]
            && !vis[adjacent[u][i]]) {
            temp++;
            dfs2(adjacent[u][i], count + 1);
        }
    }
    if (temp == 0) {
        if (maxi < count) {
            maxi = count;
            thirdnode = u;
        }
    }
}
 
// Function to find the required nodes
void findNodes()
{
    // To find start node of diameter
    dfs(1, 0);
 
    for (int i = 0; i <= N; i++)
        visited[i] = false;
 
    maxi = -1;
 
    // To find end node of diameter
    dfs1(startnode, 0);
 
    for (int i = 0; i <= N; i++)
        visited[i] = false;
 
    // x is the end node of diameter
    int x = endnode;
    vis[startnode] = true;
 
    // Mark all the nodes on diameter
    // using back tracking
    while (x != startnode) {
        vis[x] = true;
        x = parent[x];
    }
 
    maxi = -1;
 
    // Find the end node of longest
    // branch to diameter
    for (int i = 1; i <= N; i++) {
        if (vis[i])
            dfs2(i, 0);
    }
}
 
// Driver code
int main()
{
    N = 4;
    adjacent[1].push_back(2);
    adjacent[2].push_back(1);
    adjacent[1].push_back(3);
    adjacent[3].push_back(1);
    adjacent[1].push_back(4);
    adjacent[4].push_back(1);
 
    findNodes();
 
    cout << "(" << startnode << ", " << endnode
         << ", " << thirdnode << ")";
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
static int MAX = 100005;
static Vector<Vector<Integer>> adjacent = new
       Vector<Vector<Integer>> ();
static boolean visited[] = new boolean[MAX];
 
// To store the required nodes
static int startnode, endnode, thirdnode;
 
static int maxi = -1, N;
 
// Parent array to retrace the nodes
static int parent[] = new int[MAX];
 
// Visited array to prevent DFS
// in direction on Diameter path
static boolean vis[] = new boolean[MAX];
 
// DFS function to find the startnode
static void dfs(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent.get(u).size(); i++)
    {
        if (!visited[adjacent.get(u).get(i)])
        {
            temp++;
            dfs(adjacent.get(u).get(i), count + 1);
        }
    }
 
    if (temp == 0)
    {
        if (maxi < count)
        {
            maxi = count;
            startnode = u;
        }
    }
}
 
// DFS function to find the endnode
// of diameter and maintain the parent array
static void dfs1(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent.get(u).size(); i++)
    {
        if (!visited[adjacent.get(u).get(i)])
        {
            temp++;
            parent[adjacent.get(u).get(i)] = u;
            dfs1(adjacent.get(u).get(i), count + 1);
        }
    }
 
    if (temp == 0)
    {
        if (maxi < count)
        {
            maxi = count;
            endnode = u;
        }
    }
}
 
// DFS function to find the end node
// of the Longest Branch to Diameter
static void dfs2(int u, int count)
{
    visited[u] = true;
    int temp = 0;
    for (int i = 0; i < adjacent.get(u).size(); i++)
    {
        if (!visited[adjacent.get(u).get(i)] &&
            !vis[adjacent.get(u).get(i)])
        {
            temp++;
            dfs2(adjacent.get(u).get(i), count + 1);
        }
    }
    if (temp == 0)
    {
        if (maxi < count)
        {
            maxi = count;
            thirdnode = u;
        }
    }
}
 
// Function to find the required nodes
static void findNodes()
{
    // To find start node of diameter
    dfs(1, 0);
 
    for (int i = 0; i <= N; i++)
        visited[i] = false;
 
    maxi = -1;
 
    // To find end node of diameter
    dfs1(startnode, 0);
 
    for (int i = 0; i <= N; i++)
        visited[i] = false;
 
    // x is the end node of diameter
    int x = endnode;
    vis[startnode] = true;
 
    // Mark all the nodes on diameter
    // using back tracking
    while (x != startnode)
    {
        vis[x] = true;
        x = parent[x];
    }
 
    maxi = -1;
 
    // Find the end node of longest
    // branch to diameter
    for (int i = 1; i <= N; i++)
    {
        if (vis[i])
            dfs2(i, 0);
    }
}
 
// Driver code
public static void main(String args[])
{
    for(int i = 0; i < MAX; i++)
    adjacent.add(new Vector<Integer>());
     
    N = 4;
    adjacent.get(1).add(2);
    adjacent.get(2).add(1);
    adjacent.get(1).add(3);
    adjacent.get(3).add(1);
    adjacent.get(1).add(4);
    adjacent.get(4).add(1);
 
    findNodes();
 
    System.out.print( "(" + startnode + ", " +
                            endnode + ", " +
                            thirdnode + ")");
}
}
 
// This code is contributed by Arnab Kundu


Python3




# Python3 implementation of the approach
 
MAX = 100005
adjacent = [[] for i in range(MAX)]
visited = [False] * MAX
  
# To store the required nodes
startnode = endnode = thirdnode = None
maxi, N = -1, None
  
# Parent array to retrace the nodes
parent = [None] * MAX
  
# Visited array to prevent DFS
# in direction on Diameter path
vis = [False] * MAX
  
# DFS function to find the startnode
def dfs(u, count):
 
    visited[u] = True
    temp = 0
    global startnode, maxi
     
    for i in range(0, len(adjacent[u])):
        if not visited[adjacent[u][i]]:
            temp += 1
            dfs(adjacent[u][i], count + 1)
  
    if temp == 0:
        if maxi < count:
            maxi = count
            startnode = u
  
# DFS function to find the endnode of
# diameter and maintain the parent array
def dfs1(u, count):
 
    visited[u] = True
    temp = 0
    global endnode, maxi
     
    for i in range(0, len(adjacent[u])):
        if not visited[adjacent[u][i]]:
            temp += 1
            parent[adjacent[u][i]] = u
            dfs1(adjacent[u][i], count + 1)
  
    if temp == 0:
        if maxi < count:
            maxi = count
            endnode = u
         
# DFS function to find the end node
# of the Longest Branch to Diameter
def dfs2(u, count):
 
    visited[u] = True
    temp = 0
    global thirdnode, maxi
     
    for i in range(0, len(adjacent[u])):
        if (not visited[adjacent[u][i]] and
            not vis[adjacent[u][i]]):
            temp += 1
            dfs2(adjacent[u][i], count + 1)
         
    if temp == 0:
        if maxi < count:
            maxi = count
            thirdnode = u
  
# Function to find the required nodes
def findNodes():
 
    # To find start node of diameter
    dfs(1, 0)
    global maxi
  
    for i in range(0, N+1):
        visited[i] = False
  
    maxi = -1
  
    # To find end node of diameter
    dfs1(startnode, 0)
  
    for i in range(0, N+1):
        visited[i] = False
  
    # x is the end node of diameter
    x = endnode
    vis[startnode] = True
  
    # Mark all the nodes on diameter
    # using back tracking
    while x != startnode:
        vis[x] = True
        x = parent[x]
     
    maxi = -1
  
    # Find the end node of longest
    # branch to diameter
    for i in range(1, N+1):
        if vis[i]:
            dfs2(i, 0)
  
# Driver code
if __name__ == "__main__":
 
    N = 4
    adjacent[1].append(2)
    adjacent[2].append(1)
    adjacent[1].append(3)
    adjacent[3].append(1)
    adjacent[1].append(4)
    adjacent[4].append(1)
  
    findNodes()
  
    print("({}, {}, {})".format(startnode, endnode, thirdnode))
  
# This code is contributed by Rituraj Jain


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG {
     
    static int MAX = 100005;
    static List<List<int>> adjacent = new List<List<int>>();
    static bool[] visited = new bool[MAX];
      
    // To store the required nodes
    static int startnode, endnode, thirdnode;
      
    static int maxi = -1, N;
      
    // Parent array to retrace the nodes
    static int[] parent = new int[MAX];
      
    // Visited array to prevent DFS
    // in direction on Diameter path
    static bool[] vis = new bool[MAX];
      
    // DFS function to find the startnode
    static void dfs(int u, int count)
    {
        visited[u] = true;
        int temp = 0;
        for (int i = 0; i < adjacent[u].Count; i++)
        {
            if (!visited[adjacent[u][i]])
            {
                temp++;
                dfs(adjacent[u][i], count + 1);
            }
        }
      
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                startnode = u;
            }
        }
    }
      
    // DFS function to find the endnode
    // of diameter and maintain the parent array
    static void dfs1(int u, int count)
    {
        visited[u] = true;
        int temp = 0;
        for (int i = 0; i < adjacent[u].Count; i++)
        {
            if (!visited[adjacent[u][i]])
            {
                temp++;
                parent[adjacent[u][i]] = u;
                dfs1(adjacent[u][i], count + 1);
            }
        }
      
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                endnode = u;
            }
        }
    }
      
    // DFS function to find the end node
    // of the Longest Branch to Diameter
    static void dfs2(int u, int count)
    {
        visited[u] = true;
        int temp = 0;
        for (int i = 0; i < adjacent[u].Count; i++)
        {
            if (!visited[adjacent[u][i]] &&
                !vis[adjacent[u][i]])
            {
                temp++;
                dfs2(adjacent[u][i], count + 1);
            }
        }
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                thirdnode = u;
            }
        }
    }
      
    // Function to find the required nodes
    static void findNodes()
    {
        // To find start node of diameter
        dfs(1, 0);
      
        for (int i = 0; i <= N; i++)
            visited[i] = false;
      
        maxi = -1;
      
        // To find end node of diameter
        dfs1(startnode, 0);
      
        for (int i = 0; i <= N; i++)
            visited[i] = false;
      
        // x is the end node of diameter
        int x = endnode;
        vis[startnode] = true;
      
        // Mark all the nodes on diameter
        // using back tracking
        while (x != startnode)
        {
            vis[x] = true;
            x = parent[x];
        }
      
        maxi = -1;
      
        // Find the end node of longest
        // branch to diameter
        for (int i = 1; i <= N; i++)
        {
            if (vis[i])
                dfs2(i, 0);
        }
    }
 
  static void Main() {
    for(int i = 0; i < MAX; i++)
        adjacent.Add(new List<int>());
      
    N = 4;
    adjacent[1].Add(2);
    adjacent[2].Add(1);
    adjacent[1].Add(3);
    adjacent[3].Add(1);
    adjacent[1].Add(4);
    adjacent[4].Add(1);
  
    findNodes();
  
    Console.WriteLine( "(" + startnode + ", " +
                            endnode + ", " +
                            thirdnode + ")");
  }
}
 
// This code is contributed by divyeshrabadiya07.


Javascript




<script>
 
    // JavaScript implementation of the approach
     
    let MAX = 100005;
    let adjacent = [];
    let visited = new Array(MAX);
 
    // To store the required nodes
    let startnode, endnode, thirdnode;
 
    let maxi = -1, N;
 
    // Parent array to retrace the nodes
    let parent = new Array(MAX);
 
    // Visited array to prevent DFS
    // in direction on Diameter path
    let vis = new Array(MAX);
 
    // DFS function to find the startnode
    function dfs(u, count)
    {
        visited[u] = true;
        let temp = 0;
        for (let i = 0; i < adjacent[u].length; i++)
        {
            if (!visited[adjacent[u][i]])
            {
                temp++;
                dfs(adjacent[u][i], count + 1);
            }
        }
 
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                startnode = u;
            }
        }
    }
 
    // DFS function to find the endnode
    // of diameter and maintain the parent array
    function dfs1(u, count)
    {
        visited[u] = true;
        let temp = 0;
        for (let i = 0; i < adjacent[u].length; i++)
        {
            if (!visited[adjacent[u][i]])
            {
                temp++;
                parent[adjacent[u][i]] = u;
                dfs1(adjacent[u][i], count + 1);
            }
        }
 
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                endnode = u;
            }
        }
    }
 
    // DFS function to find the end node
    // of the Longest Branch to Diameter
    function dfs2(u, count)
    {
        visited[u] = true;
        let temp = 0;
        for (let i = 0; i < adjacent[u].length; i++)
        {
            if (!visited[adjacent[u][i]] &&
                !vis[adjacent[u][i]])
            {
                temp++;
                dfs2(adjacent[u][i], count + 1);
            }
        }
        if (temp == 0)
        {
            if (maxi < count)
            {
                maxi = count;
                thirdnode = u;
            }
        }
    }
 
    // Function to find the required nodes
    function findNodes()
    {
        // To find start node of diameter
        dfs(1, 0);
 
        for (let i = 0; i <= N; i++)
            visited[i] = false;
 
        maxi = -1;
 
        // To find end node of diameter
        dfs1(startnode, 0);
 
        for (let i = 0; i <= N; i++)
            visited[i] = false;
 
        // x is the end node of diameter
        let x = endnode;
        vis[startnode] = true;
 
        // Mark all the nodes on diameter
        // using back tracking
        while (x != startnode)
        {
            vis[x] = true;
            x = parent[x];
        }
 
        maxi = -1;
 
        // Find the end node of longest
        // branch to diameter
        for (let i = 1; i <= N; i++)
        {
            if (vis[i])
                dfs2(i, 0);
        }
    }
     
    for(let i = 0; i < MAX; i++)
        adjacent.push([]);
       
    N = 4;
    adjacent[1].push(2);
    adjacent[2].push(1);
    adjacent[1].push(3);
    adjacent[3].push(1);
    adjacent[1].push(4);
    adjacent[4].push(1);
   
    findNodes();
   
    document.write( "(" + startnode + ", " +
                            endnode + ", " +
                            thirdnode + ")");
     
</script>


Output: 

(2, 3, 4)

 

Time Complexity: O(N+M) where N is the number of nodes in the graph and M is the number of edges in the graph.
Auxiliary Space: O(MAX)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads