📜  树的每个节点与给定的断开组件连接后的直径

📅  最后修改于: 2021-10-27 07:19:43             🧑  作者: Mango

给定一棵树,它具有由N-1 条边连接的N 个节点和一个断开的节点,任务是在将给定的树与给定的断开组件连接后找到给定树的每个节点的直径。

例子:

处理方法:为解决该问题,需要进行以下观察:

根据以上观察,按照下面给出的步骤解决问题:

  1. 执行给定树的 DFS 遍历。
  2. 在遍历时,跟踪所经过的最远距离和最远节点。
  3. 现在,从上一步得到的最远节点开始执行DFS ,并跟踪距离该节点最远的节点。
  4. 现在,执行DFS并分别在距离上述步骤获得的两个节点最远的Map中添加节点。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Keeps track of the farthest
// end of the diameter
int X = 1;
 
// Keeps track of the length of
// the diameter
int diameter = 0;
 
// Stores the nodes which are at
// ends of the diameter
map mp;
 
// Perform DFS on the given tree
void dfs(int current_node, int prev_node,
         int len, bool add_to_map,
         vector >& adj)
{
    // Update diameter and X
    if (len > diameter) {
        diameter = len;
        X = current_node;
    }
 
    // If current node is an end of diameter
    if (add_to_map && len == diameter) {
        mp[current_node] = 1;
    }
 
    // Traverse its neighbors
    for (auto& it : adj[current_node]) {
        if (it != prev_node)
            dfs(it, current_node, len + 1,
                add_to_map, adj);
    }
}
 
// Function to call DFS for the
// required purposes
void dfsUtility(vector >& adj)
{
    // DFS from a random node and find
    // the node farthest from it
    dfs(1, -1, 0, 0, adj);
 
    int farthest_node = X;
 
    // DFS from X to calculate diameter
    dfs(farthest_node, -1, 0, 0, adj);
 
    // DFS from farthest_node to find
    // the farthest node(s) from it
    dfs(farthest_node, -1, 0, 1, adj);
 
    // DFS from X (other end of diameter) and
    // check the farthest node(s) from it
    dfs(X, -1, 0, 1, adj);
}
 
void printDiameters(vector >& adj)
{
    dfsUtility(adj);
 
    for (int i = 1; i <= 6; i++) {
 
        // If node i is the end of
        // a diameter
        if (mp[i] == 1)
 
            // Increase diameter by 1
            cout << diameter + 1 << ",  ";
 
        // Otherwise
        else
 
            // Remains unchanged
            cout << diameter << ",  ";
    }
}
 
// Driver Code
int main()
{
 
    /* constructed tree is
            1
           / \
          2   3    7
         /|\
        / | \
       4  5  6    */
 
    vector > adj(7);
 
    // creating undirected edges
    adj[1].push_back(2);
    adj[2].push_back(1);
    adj[1].push_back(3);
    adj[3].push_back(1);
    adj[2].push_back(4);
    adj[4].push_back(2);
    adj[2].push_back(5);
    adj[5].push_back(2);
    adj[2].push_back(6);
    adj[6].push_back(2);
 
    printDiameters(adj);
 
    return 0;
}


Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
 
// Keeps track of the farthest
// end of the diameter
static int X = 1;
 
// Keeps track of the length of
// the diameter
static int diameter = 0;
 
// Stores the nodes which are at
// ends of the diameter
static HashMap mp = new HashMap<>();
 
// Perform DFS on the given tree
static void dfs(int current_node, int prev_node,
                 int len, boolean add_to_map,
                Vector []  adj)
{
    // Update diameter and X
    if (len > diameter)
    {
        diameter = len;
        X = current_node;
    }
 
    // If current node is an end of diameter
    if (add_to_map && len == diameter)
    {
        mp.put(current_node, true);
    }
 
    // Traverse its neighbors
    for (int it : adj[current_node])
    {
        if (it != prev_node)
            dfs(it, current_node, len + 1,
                add_to_map, adj);
    }
}
 
// Function to call DFS for the
// required purposes
static void dfsUtility(Vector []  adj)
{
    // DFS from a random node and find
    // the node farthest from it
    dfs(1, -1, 0, false, adj);
 
    int farthest_node = X;
 
    // DFS from X to calculate diameter
    dfs(farthest_node, -1, 0, false, adj);
 
    // DFS from farthest_node to find
    // the farthest node(s) from it
    dfs(farthest_node, -1, 0, true, adj);
 
    // DFS from X (other end of diameter) and
    // check the farthest node(s) from it
    dfs(X, -1, 0, true, adj);
}
 
static void printDiameters(Vector [] adj)
{
    dfsUtility(adj);
 
    for (int i = 1; i <= 6; i++)
    {
 
        // If node i is the end of
        // a diameter
        if (mp.containsKey(i) &&
            mp.get(i) == true)
 
            // Increase diameter by 1
            System.out.print(diameter + 1 + ",  ");
 
        // Otherwise
        else
 
            // Remains unchanged
            System.out.print(diameter + ",  ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
 
    /* constructed tree is
            1
           / \
          2   3    7
         /|\
        / | \
       4  5  6    */
 
    Vector []adj = new Vector[7];
    for (int i = 0; i < adj.length; i++)
        adj[i] = new Vector();
   
    // creating undirected edges
    adj[1].add(2);
    adj[2].add(1);
    adj[1].add(3);
    adj[3].add(1);
    adj[2].add(4);
    adj[4].add(2);
    adj[2].add(5);
    adj[5].add(2);
    adj[2].add(6);
    adj[6].add(2);
 
    printDiameters(adj);
}
}
 
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to implement
# the above approach
from collections import defaultdict
 
# Keeps track of the farthest
# end of the diameter
X = 1
 
# Keeps track of the length of
# the diameter
diameter = 0
 
# Stores the nodes which are at
# ends of the diameter
mp = defaultdict(lambda :0)
 
# Perform DFS on the given tree
def dfs(current_node, prev_node,
        len, add_to_map, adj):
             
    global diameter, X
     
    # Update diameter and X
    if len > diameter:
        diameter = len
        X = current_node
     
    # If current node is an end of diameter
    if add_to_map and len == diameter:
        mp[current_node] = 1
     
    # Traverse its neighbors
    for it in adj[current_node]:
        if it != prev_node:
            dfs(it, current_node, len + 1,
                add_to_map, adj)
             
# Function to call DFS for the
# required purposes
def dfsUtility(adj):
     
    # DFS from a random node and find
    # the node farthest from it
    dfs(1, -1, 0, 0, adj)
     
    farthest_node = X
     
    # DFS from X to calculate diameter
    dfs(farthest_node, -1, 0, 0, adj)
     
    # DFS from farthest_node to find
    # the farthest node(s) from it
    dfs(farthest_node, -1, 0, 1, adj)
     
    # DFS from X (other end of diameter) and
    # check the farthest node(s) from it
    dfs(X, -1, 0, 1, adj)
     
def printDiameters(adj):
     
    global diameter
    dfsUtility(adj)
     
    for i in range(1, 6 + 1):
         
        # If node i is the end of
        # a diameter
        if mp[i] == 1:
             
            # Increase diameter by 1
            print(diameter + 1, end = ", ")
             
        # Otherwise
        else:
             
            # Remains unchanged
            print(diameter, end = ", ")
             
# Driver code
     
# constructed tree is
#         1
#        / \
#      2   3
#    / | \
#   4  5  6
#      |
#      7
 
adj = []
for i in range(7):
    adj.append([])
     
# Creating undirected edges
adj[1].append(2)
adj[2].append(1)
adj[1].append(3)
adj[3].append(1)
adj[2].append(4)
adj[4].append(2)
adj[2].append(5)
adj[5].append(2)
adj[2].append(6)
adj[6].append(2)
 
printDiameters(adj)
 
# This code is contributed by Stuti Pathak


C#
// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
 
    // Keeps track of the farthest
    // end of the diameter
    static int X = 1;
 
    // Keeps track of the
    // length of the diameter
    static int diameter = 0;
 
    // Stores the nodes which are at
    // ends of the diameter
    static Dictionary mp
        = new Dictionary();
 
    // Perform DFS on the given tree
    static void dfs(int current_node, int prev_node,
                    int len, bool add_to_map,
                    List[] adj)
    {
        // Update diameter and X
        if (len > diameter)
        {
            diameter = len;
            X = current_node;
        }
 
        // If current node is an end of diameter
        if (add_to_map && len == diameter)
        {
            mp.Add(current_node, true);
        }
 
        // Traverse its neighbors
        foreach(int it in adj[current_node])
        {
            if (it != prev_node)
                dfs(it, current_node, len + 1,
                    add_to_map, adj);
        }
    }
 
    // Function to call DFS for
    // the required purposes
    static void dfsUtility(List[] adj)
    {
 
        // DFS from a random node and find
        // the node farthest from it
        dfs(1, -1, 0, false, adj);
 
        int farthest_node = X;
 
        // DFS from X to calculate diameter
        dfs(farthest_node, -1, 0, false, adj);
 
        // DFS from farthest_node to find
        // the farthest node(s) from it
        dfs(farthest_node, -1, 0, true, adj);
 
        // DFS from X (other end of diameter) and
        // check the farthest node(s) from it
        dfs(X, -1, 0, true, adj);
    }
 
    static void printDiameters(List[] adj)
    {
        dfsUtility(adj);
 
        for (int i = 1; i <= 6; i++)
        {
 
            // If node i is the end
            // of a diameter
            if (mp.ContainsKey(i) && mp[i] == true)
 
                // Increase diameter by 1
                Console.Write(diameter + 1 + ",  ");
 
            // Otherwise
            else
 
                // Remains unchanged
                Console.Write(diameter + ",  ");
        }
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
 
        /* constructed tree is
            1
           / \
          2   3    7
         /|\
        / | \
       4  5  6    */
 
        List[] adj = new List[ 7 ];
        for (int i = 0; i < adj.Length; i++)
            adj[i] = new List();
 
        // creating undirected edges
        adj[1].Add(2);
        adj[2].Add(1);
        adj[1].Add(3);
        adj[3].Add(1);
        adj[2].Add(4);
        adj[4].Add(2);
        adj[2].Add(5);
        adj[5].Add(2);
        adj[2].Add(6);
        adj[6].Add(2);
        printDiameters(adj);
    }
}
 
// This code is contributed by Amit Katiyar


Javascript


输出:
3,  3,  4,  4,  4,  4,

时间复杂度: O(V + E) ,其中 V 是顶点数,E 是图中的边数。
辅助空间: O(V)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程