You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何找到树中被最多叶到叶路径经过的节点?dp-on-tree解法求助

解题思路

这个问题的核心是计算每个节点被多少条叶到叶路径经过,最终取数值最大的对应节点即可,不需要复杂的换根DP,仅通过两次线性遍历就能实现。
首先明确:树中任意一条叶到叶路径经过节点u的充要条件是,路径的两个端点分别位于删除u后形成的不同连通块中。基于这个性质可以快速推导每个节点的路径计数。

算法步骤
  1. 统计整棵树的总叶子节点数M:叶子节点定义为度数为1的节点,若M≤1说明不存在叶到叶路径,直接返回任意节点即可。
  2. 任选根节点(比如1号节点),做一次后序DFS预处理dp数组:dp[u]表示以u为根的子树内的叶子节点总数。
    • 若u本身是叶子节点,dp[u] = 1
    • 否则dp[u]等于所有子节点的dp值之和
  3. 遍历每个节点u,计算经过它的路径总数:
    • 删除u后,树会拆分为k个连通块(k等于u的度数),每个连通块的叶子数分别为s_1, s_2, ...s_k
    • 对于u的子节点对应的连通块,s_i = dp[v](v为u的子节点)
    • 对于u的父节点方向的连通块,s_i = M - dp[u]
    • 经过u的路径数 = 总叶到叶路径数 - 所有连通块内部的叶到叶路径数
  4. 遍历所有节点取路径数最大的节点即为答案。
核心公式

总叶到叶路径数为 total = M*(M-1)//2
每个节点u的路径计数:
ans[u] = total - sum( s_i*(s_i-1)//2 for all s_i )
你给出的示例中M=5,total=10,节点2删除后连通块的叶子数分别为1、1、1、2,sum值为0+0+0+1=1,所以ans[2]=10-1=9,和你给出的路径数完全匹配。

代码实现
import sys
sys.setrecursionlimit(1 << 25)

def main():
    input = sys.stdin.read
    data = input().split()
    idx = 0
    N = int(data[idx])
    idx += 1
    adj = [[] for _ in range(N + 1)]
    for _ in range(N - 1):
        u = int(data[idx])
        v = int(data[idx + 1])
        adj[u].append(v)
        adj[v].append(u)
        idx += 2
    
    # 统计总叶子数
    M = 0
    for i in range(1, N + 1):
        if len(adj[i]) == 1:
            M += 1
    if M <= 1:
        print(1)
        return
    
    dp = [0] * (N + 1)
    # 后序DFS计算dp数组
    def dfs(u, parent):
        if len(adj[u]) == 1:
            dp[u] = 1
            return
        cnt = 0
        for v in adj[u]:
            if v == parent:
                continue
            dfs(v, u)
            cnt += dp[v]
        dp[u] = cnt
    
    dfs(1, -1)
    total = M * (M - 1) // 2
    max_cnt = -1
    res_node = 1
    
    # 计算每个节点的路径数
    for u in range(1, N + 1):
        sum_same = 0
        for v in adj[u]:
            # 判断v是子节点还是父节点
            if dp[v] < dp[u] or (len(adj[v]) == 1 and dp[v] == 1):
                si = dp[v]
            else:
                si = M - dp[u]
            sum_same += si * (si - 1) // 2
        cur = total - sum_same
        if cur > max_cnt:
            max_cnt = cur
            res_node = u
    print(res_node)

if __name__ == "__main__":
    main()

代码时间复杂度为O(N),可以处理规模较大的树。

内容的提问来源于stack exchange,提问作者Lam Cherry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:45:02