📜  查找三元组,以使连接这些三元组的节点数最大

📅  最后修改于: 2021-04-17 12:33:35             🧑  作者: Mango

给定一棵具有N个节点的树,任务是找到一个三元组的节点(a,b,c) ,以使连接这些节点的路径中覆盖的节点数最大。 (仅对节点计数一次)。

例子:

方法:

  • 需要注意的重要一点是,三元组中的两个点必须是树的直径的末端,以覆盖最大的点。
  • 我们需要找到最长的支杆直径。
  • 现在,对于第3个节点,将DFS应用于每个节点的深度(除选定的Diameter Path以外的所有方向上的DFS),并应用到存在于Diameter路径上的所有节点(距离最远的节点)为被视为第三个节点,因为它覆盖了直径节点已经覆盖的最大节点。使用DFS的树的直径

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#define ll long long int
#define MAX 100005
using namespace std;
vector 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> adjacent = new 
       Vector> ();
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());
      
    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


输出:
(2, 3, 4)