B4016 树的直径

B4016 树的直径 - 树形DP解法

解题思路

这道题目要求计算树的直径,即树中最长的无重复节点的路径长度。我们使用树形DP的方法来解决:

  1. 核心思想:对于每个节点,计算通过它的最长路径(即两个最深子树的深度之和)

  2. 递归过程:DFS遍历树,维护每个节点的最大深度和次大深度

  3. 直径更新:在回溯过程中,用当前节点的max1 + max2更新全局直径

代码注释

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

vector<int> g[N];  // 邻接表存储树结构
int n;             // 节点数量
int dep[N];        // dep[x]表示以x为根的子树的最大深度
int ans;           // 存储树的直径

// DFS遍历计算树的直径
void dfs(int x, int fa) {
    int maxx1 = 0, maxx2 = 0;  // 记录当前节点的两个最大子树深度
    
    // 遍历所有子节点
    for(int i = 0; i < g[x].size(); i++) {
        int y = g[x][i];
        if(y == fa) continue;  // 跳过父节点避免回溯
        
        dfs(y, x);  // 递归处理子节点
        
        // 更新最大和次大深度
        if(dep[y] > maxx1) {
            maxx2 = maxx1;    // 原来的最大值变为次大值
            maxx1 = dep[y];   // 更新最大值
        }
        else if(dep[y] > maxx2) {
            maxx2 = dep[y];   // 更新次大值
        }
    }
    
    // 更新当前节点的深度(最大子树深度+1)
    dep[x] = maxx1 + 1;
    
    // 用通过当前节点的最长路径更新直径
    ans = max(ans, maxx1 + maxx2);
}

int main() {
    cin >> n;
    
    // 构建树结构
    for(int i = 1; i < n; i++) {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    
    // 从根节点(1)开始DFS计算直径
    dfs(1, 0);
    
    // 输出直径长度
    cout << ans;
    
    return 0;
}

 

posted @ 2025-06-13 16:42  CRt0729  阅读(53)  评论(0)    收藏  举报