📌  相关文章
📜  国际空间研究组织 | ISRO CS 2017 |问题 38(1)

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

国际空间研究组织 | ISRO CS 2017 | 题目 38

该题目是一道关于树的题目,我们需要在给定的树中查找任意两个节点的距离,最后输出距离的和。以下是题目的具体描述:

给定一个树,其中树结构由无序对 u 和 v 的值以及它们之间的距离组成。现在,假设要从树中找到两个节点之间的距离并返回它们的总和。

输入格式

输入包含一个整数 T,表示测试用例的数量。然后是 T 个测试用例,每个测试用例都有以下格式:

第一行包含一个整数 N,表示树中节点的数量。

接下来的 N-1 行包含无序对 u 和 v 的值,以及它们之间的距离。

输出格式

对于每个测试用例,都要在新行上输出总和。

样例输入
1
3
1 2 1
2 3 2
样例输出
6
解释

在上面的示例中,有以下两个节点对:

  • [1, 2] 之间的距离为 1
  • [1, 3] 之间的距离为 3

因此,输出总和为 6。

解题思路

该题目要求我们求出树中任意两个节点之间的距离并求和,我们可以考虑使用DFS(深度优先搜索)的方式来遍历所有的节点对,然后利用最近公共祖先算法来求每个节点对之间的距离。

算法步骤
  1. 从根节点开始,进行深度优先搜索
  2. 对于每个节点,我们需要找到它的所有子节点,并记录它们和它的距离
  3. 对于每一对节点,我们可以利用公式 $LCA_{i,j} = LCA(LCA_{i,p},LCA_{j,p})$ 来求它们的最近公共祖先 $p$
  4. 最终,我们可以使用以下公式来计算节点对之间的距离:$d_{i,j} = d_i + d_j - 2d_p$
  5. 最后,我们将所有节点之间的距离累加,得到最终答案
算法复杂度分析
  • 时间复杂度:$O(N^2)$,其中 N 表示树中节点的数量
  • 空间复杂度:$O(N)$,其中 N 表示树中节点的数量
代码实现
def dfs(u, p, dist):
    # u:当前节点
    # p:u 的父节点
    # dist:u 到根节点的距离

    global ans

    for v, w in tree[u]:
        if v != p:
            dfs(v, u, dist + w)
            ans += (dist + w) * (n - (size[v] if v != p else size[u]))

# 计算子树大小
def calc_size(u, p):
    size[u] = 1
    for v, w in tree[u]:
        if v != p:
            calc_size(v, u)
            size[u] += size[v]

# 计算 LCA
def calc_lca(u, v):
    if depth[u] < depth[v]:
        u, v = v, u
    while depth[u] > depth[v]:
        u = parent[u]
    while u != v:
        u = parent[u]
        v = parent[v]
    return u

# 初始化
def init():
    global ans, tree, size, parent, depth
    ans = 0
    tree = [[] for i in range(n+1)]
    size = [0] * (n+1)
    parent = [0] * (n+1)
    depth = [0] * (n+1)

# 处理每个测试用例
for _ in range(T):
    n = int(input())
    init()
    for i in range(n-1):
        u, v, w = map(int, input().split())
        tree[u].append((v, w))
        tree[v].append((u, w))

    calc_size(1, 0)
    for u in range(1, n+1):
        for v, w in tree[u]:
            if v != parent[u]:
                parent[v] = u
                depth[v] = depth[u] + 1

    for u in range(1, n+1):
        for v, w in tree[u]:
            if v != parent[u]:
                p = calc_lca(u, v)
                ans += w * (size[v] if v != p else n - size[u])
    print(ans)
总结

该题目涉及到了树的相关算法,需要我们将树中的节点遍历一遍,并计算每个节点之间的距离。同时,需要注意算法中的一些细节问题,如计算节点子树大小、LCA 等。