树型动态规划是一类用于树形结构问题的动态规划技术,通常用于解决涉及树(如二叉树、通用树等)的问题。它的基本思想是利用递归和子问题的结果来构建整个问题的解。树型动态规划在树的每个节点上进行状态转移,通常通过后序遍历(Postorder Traversal)从叶子节点到根节点计算子问题的最优解,再逐步合并这些子问题的解以得到整个树的最优解。
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /**************************************************************** * Description: treeDP 1、输入:树的边信息。 2、dfs函数:计算以每个节点为根的子树的最大深度,并更新经过该节点的最大路径。 3、状态:dp[u] 存储以节点 u 为中心的最长路径。 4、结果:树的直径可以通过计算所有节点的 dp[u] 中的最大值来得到。 * Author: Alex Li * Date: 2024-08-14 13:57:42 * LastEditTime: 2024-08-14 13:57:57 ****************************************************************/ #include <iostream> #include <vector> #include <algorithm> using namespace std; vector<vector<int>> tree; vector<int> dp; // 辅助函数:计算以节点 u 为根的子树的最大深度,并更新树的直径 int dfs(int u, int parent) { int max1 = 0, max2 = 0; // 记录两个最大的子树深度 for (int v : tree[u]) { if (v == parent) continue; int depth = dfs(v, u) + 1; if (depth > max1) { max2 = max1; max1 = depth; } else if (depth > max2) { max2 = depth; } } dp[u] = max1 + max2; // 更新经过节点 u 的最大路径 return max1; // 返回该子树的最大深度 } int main() { int n; cin >> n; tree.resize(n); dp.resize(n, 0); for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; tree[u].push_back(v); tree[v].push_back(u); } dfs(0, -1); // int diameter = *max_element(dp.begin(), dp.end()); int diameter = 0; for (int i = 0; i < n; ++i) { diameter = max(diameter, dp[i]); } cout << "Tree Diameter: " << diameter << endl; return 0; } |