B4016 树的直径
B4016 树的直径 - 树形DP解法
解题思路
这道题目要求计算树的直径,即树中最长的无重复节点的路径长度。我们使用树形DP的方法来解决:
-
核心思想:对于每个节点,计算通过它的最长路径(即两个最深子树的深度之和)
-
递归过程:DFS遍历树,维护每个节点的最大深度和次大深度
-
直径更新:在回溯过程中,用当前节点的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; }

浙公网安备 33010602011771号