📜  查找树中距每个节点最远的节点(1)

📅  最后修改于: 2023-12-03 15:40:24.853000             🧑  作者: Mango

查找树中距每个节点最远的节点

简介

在一颗树中,对于每个节点,找到该节点到树中距离它最远的节点。

解法

对于一棵树来说,树的直径上的任意一个节点(也可以是多个节点)到其他节点的距离均不会超过树的直径的一半。所以我们可以首先求出树的直径,然后以直径上的任意一个节点(也可以是多个节点)为根节点,分别求出该节点到所有其他节点的最短距离,再取其中的最大值,即为该节点到树中距离它最远的节点。

求树的直径可以使用树的直径算法,时间复杂度为 O(n)。求出直径之后,可以通过 BFS 或 DFS 分别求出直径上的任意一个节点到其他节点的最短距离。总时间复杂度为 O(n)。

代码实现
# 求树的直径
def tree_diameter(graph):
    n = len(graph)
    dist = [-1] * n
    dist[0] = 0
    q = [0]

    # BFS 从任意一个节点开始搜索
    while q:
        u = q.pop(0)
        for v in graph[u]:
            if dist[v] == -1:
                dist[v] = dist[u] + 1
                q.append(v)

    # 找到距离最远的节点
    u = max(range(n), key=lambda x: dist[x])

    dist = [-1] * n
    dist[u] = 0
    q = [u]

    # BFS 从最远节点开始搜索
    while q:
        u = q.pop(0)
        for v in graph[u]:
            if dist[v] == -1:
                dist[v] = dist[u] + 1
                q.append(v)

    # 找到距离最远的节点
    v = max(range(n), key=lambda x: dist[x])

    return (u, v, dist[v])

# 对于每个节点,求出该节点到树中距离它最远的节点
def farthest_node(graph):
    n = len(graph)
    diameter = tree_diameter(graph)
    root = diameter[0]
    dist = [-1] * n
    dist[root] = 0
    q = [root]

    # BFS 从直径上任意一个节点开始搜索
    while q:
        u = q.pop(0)
        for v in graph[u]:
            if dist[v] == -1:
                dist[v] = dist[u] + 1
                q.append(v)

    res = [max(dist[i], diameter[2] - dist[i]) for i in range(n)]
    return res