📜  节点到树的每个节点的最远距离

📅  最后修改于: 2021-04-29 11:00:08             🧑  作者: Mango

给定一棵树,任务是找到给定树中从每个节点到另一个节点最远的节点。

例子

方法:

请按照以下步骤解决问题:

  • 使用DFS计算树的每个节点的高度(假设叶节点的高度为1)
  • 这给出了从一个节点到其子树中存在的所有节点的最大距离。存放这些高度。
  • 现在,执行DFS计算节点到其所有祖先的最大距离。存储这些距离。
  • 对于每个节点,请打印计算出的两个距离中的最大值。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
#define maxN 100001
 
// Adjacency List to store the graph
vector adj[maxN];
 
// Stores the height of each node
int height[maxN];
 
// Stores the maximum distance of a
// node from its ancestors
int dist[maxN];
 
// Function to add edge between
// two vertices
void addEdge(int u, int v)
{
    // Insert edge from u to v
    adj[u].push_back(v);
 
    // Insert edge from v to u
    adj[v].push_back(u);
}
 
// Function to calculate height of
// each Node
void dfs1(int cur, int par)
{
    // Iterate in the adjacency
    // list of the current node
    for (auto u : adj[cur]) {
 
        if (u != par) {
 
            // Dfs for child node
            dfs1(u, cur);
 
            // Calculate height of nodes
            height[cur]
                = max(height[cur], height[u]);
        }
    }
 
    // Increase height
    height[cur] += 1;
}
 
// Function to calculate the maximum
// distance of a node from its ancestor
void dfs2(int cur, int par)
{
    int max1 = 0;
    int max2 = 0;
 
    // Iterate in the adjacency
    // list of the current node
    for (auto u : adj[cur]) {
 
        if (u != par) {
 
            // Find two children
            // with maximum heights
            if (height[u] >= max1) {
                max2 = max1;
                max1 = height[u];
            }
            else if (height[u] > max2) {
                max2 = height[u];
            }
        }
    }
 
    int sum = 0;
 
    for (auto u : adj[cur]) {
        if (u != par) {
 
            // Calculate the maximum distance
            // with ancestor for every node
            sum = ((max1 == height[u]) ? max2 : max1);
 
            if (max1 == height[u])
                dist[u]
                    = 1 + max(1 + max2, dist[cur]);
            else
                dist[u]
                    = 1 + max(1 + max1, dist[cur]);
 
            // Calculating for children
            dfs2(u, cur);
        }
    }
}
 
// Driver Code
int main()
{
    int n = 6;
 
    addEdge(1, 2);
    addEdge(2, 3);
    addEdge(2, 4);
    addEdge(2, 5);
    addEdge(5, 6);
 
    // Calculate height of
    // nodes of the tree
    dfs1(1, 0);
 
    // Calculate the maximum
    // distance with ancestors
    dfs2(1, 0);
 
    // Print the maximum of the two
    // distances from each node
    for (int i = 1; i <= n; i++)
        cout << (max(dist[i], height[i]) - 1) << " ";
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
static final int maxN = 100001;
 
// Adjacency List to store the graph
@SuppressWarnings("unchecked")
static Vector []adj = new Vector[maxN];
 
// Stores the height of each node
static int []height = new int[maxN];
 
// Stores the maximum distance of a
// node from its ancestors
static int []dist = new int[maxN];
 
// Function to add edge between
// two vertices
static void addEdge(int u, int v)
{
     
    // Insert edge from u to v
    adj[u].add(v);
 
    // Insert edge from v to u
    adj[v].add(u);
}
 
// Function to calculate height of
// each Node
static void dfs1(int cur, int par)
{
     
    // Iterate in the adjacency
    // list of the current node
    for(int u : adj[cur])
    {
        if (u != par)
        {
             
            // Dfs for child node
            dfs1(u, cur);
 
            // Calculate height of nodes
            height[cur] = Math.max(height[cur],
                                   height[u]);
        }
    }
 
    // Increase height
    height[cur] += 1;
}
 
// Function to calculate the maximum
// distance of a node from its ancestor
static void dfs2(int cur, int par)
{
    int max1 = 0;
    int max2 = 0;
 
    // Iterate in the adjacency
    // list of the current node
    for(int u : adj[cur])
    {
        if (u != par)
        {
             
            // Find two children
            // with maximum heights
            if (height[u] >= max1)
            {
                max2 = max1;
                max1 = height[u];
            }
            else if (height[u] > max2)
            {
                max2 = height[u];
            }
        }
    }
    int sum = 0;
 
    for(int u : adj[cur])
    {
        if (u != par)
        {
             
            // Calculate the maximum distance
            // with ancestor for every node
            sum = ((max1 == height[u]) ?
                    max2 : max1);
 
            if (max1 == height[u])
                dist[u] = 1 + Math.max(1 + max2,
                                       dist[cur]);
            else
                dist[u] = 1 + Math.max(1 + max1,
                                       dist[cur]);
 
            // Calculating for children
            dfs2(u, cur);
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int n = 6;
    for(int i = 0; i < adj.length; i++)
        adj[i] = new Vector();
         
    addEdge(1, 2);
    addEdge(2, 3);
    addEdge(2, 4);
    addEdge(2, 5);
    addEdge(5, 6);
 
    // Calculate height of
    // nodes of the tree
    dfs1(1, 0);
 
    // Calculate the maximum
    // distance with ancestors
    dfs2(1, 0);
 
    // Print the maximum of the two
    // distances from each node
    for(int i = 1; i <= n; i++)
        System.out.print((Math.max(dist[i],
                                 height[i]) - 1) + " ");
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to implement
# the above approach
maxN = 100001
 
# Adjacency List to store the graph
adj = [[] for i in range(maxN)]
  
# Stores the height of each node
height = [0 for i in range(maxN)]
  
# Stores the maximum distance of a
# node from its ancestors
dist = [0 for i in range(maxN)]
  
# Function to add edge between
# two vertices
def addEdge(u, v):
 
    # Insert edge from u to v
    adj[u].append(v)
  
    # Insert edge from v to u
    adj[v].append(u)
 
# Function to calculate height of
# each Node
def dfs1(cur, par):
 
    # Iterate in the adjacency
    # list of the current node
    for u in adj[cur]:
        if (u != par):
  
            # Dfs for child node
            dfs1(u, cur)
  
            # Calculate height of nodes
            height[cur] = max(height[cur],
                              height[u])
  
    # Increase height
    height[cur] += 1
 
# Function to calculate the maximum
# distance of a node from its ancestor
def dfs2(cur, par):
 
    max1 = 0
    max2 = 0
  
    # Iterate in the adjacency
    # list of the current node
    for u in adj[cur]:
        if (u != par):
  
            # Find two children
            # with maximum heights
            if (height[u] >= max1):
                max2 = max1
                max1 = height[u]
             
            elif (height[u] > max2):
                max2 = height[u]
  
    sum = 0
     
    for u in adj[cur]:
        if (u != par):
  
            # Calculate the maximum distance
            # with ancestor for every node
            sum = (max2 if (max1 == height[u]) else max1)
  
            if (max1 == height[u]):
                dist[u] = 1 + max(1 + max2, dist[cur])
            else:
                dist[u] = 1 + max(1 + max1, dist[cur])
  
            # Calculating for children
            dfs2(u, cur)
         
# Driver Code
if __name__=="__main__":
 
    n = 6
  
    addEdge(1, 2)
    addEdge(2, 3)
    addEdge(2, 4)
    addEdge(2, 5)
    addEdge(5, 6)
  
    # Calculate height of
    # nodes of the tree
    dfs1(1, 0)
  
    # Calculate the maximum
    # distance with ancestors
    dfs2(1, 0)
     
    # Print the maximum of the two
    # distances from each node
    for i in range(1, n + 1):
        print(max(dist[i],
                height[i]) - 1, end = ' ')
  
# This code is contributed by rutvik_56


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static readonly int maxN = 100001;
 
// Adjacency List to store the graph
static List []adj = new List[maxN];
 
// Stores the height of each node
static int []height = new int[maxN];
 
// Stores the maximum distance of a
// node from its ancestors
static int []dist = new int[maxN];
 
// Function to add edge between
// two vertices
static void addEdge(int u, int v)
{
     
    // Insert edge from u to v
    adj[u].Add(v);
 
    // Insert edge from v to u
    adj[v].Add(u);
}
 
// Function to calculate height of
// each Node
static void dfs1(int cur, int par)
{
     
    // Iterate in the adjacency
    // list of the current node
    foreach(int u in adj[cur])
    {
        if (u != par)
        {
             
            // Dfs for child node
            dfs1(u, cur);
 
            // Calculate height of nodes
            height[cur] = Math.Max(height[cur],
                                   height[u]);
        }
    }
 
    // Increase height
    height[cur] += 1;
}
 
// Function to calculate the maximum
// distance of a node from its ancestor
static void dfs2(int cur, int par)
{
    int max1 = 0;
    int max2 = 0;
 
    // Iterate in the adjacency
    // list of the current node
    foreach(int u in adj[cur])
    {
        if (u != par)
        {
             
            // Find two children
            // with maximum heights
            if (height[u] >= max1)
            {
                max2 = max1;
                max1 = height[u];
            }
            else if (height[u] > max2)
            {
                max2 = height[u];
            }
        }
    }
    int sum = 0;
 
    foreach(int u in adj[cur])
    {
        if (u != par)
        {
             
            // Calculate the maximum distance
            // with ancestor for every node
            sum = ((max1 == height[u]) ?
                    max2 : max1);
 
            if (max1 == height[u])
                dist[u] = 1 + Math.Max(1 + max2,
                                       dist[cur]);
            else
                dist[u] = 1 + Math.Max(1 + max1,
                                       dist[cur]);
 
            // Calculating for children
            dfs2(u, cur);
        }
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    int n = 6;
    for(int i = 0; i < adj.Length; i++)
        adj[i] = new List();
         
    addEdge(1, 2);
    addEdge(2, 3);
    addEdge(2, 4);
    addEdge(2, 5);
    addEdge(5, 6);
 
    // Calculate height of
    // nodes of the tree
    dfs1(1, 0);
 
    // Calculate the maximum
    // distance with ancestors
    dfs2(1, 0);
 
    // Print the maximum of the two
    // distances from each node
    for(int i = 1; i <= n; i++)
        Console.Write((Math.Max(dist[i],
                                height[i]) - 1) + " ");
}
}
 
// This code is contributed by Rohit_ranjan


输出:
3 2 3 3 2 3






时间复杂度: O(V + E)
辅助空间: O(N)