📌  相关文章
📜  将树与给定的断开连接连接后,树的每个节点的直径

📅  最后修改于: 2021-05-07 06:47:24             🧑  作者: 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


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




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