浅谈树形DP
树形DP是动态规划中最难也最常考的内容。具有DP和图论相结合的特点。
但从本质上来说,树形DP只不过是一种线性DP,只是将它与搜索结合起来了而已。
树形DP的基本步骤
读图
树形DP的题目中,通常会给出一个树,因此我们首先把图读入并存储(建议用链式向前星QAQ \(vector\)好卡啊)
深搜
树形DP一般要借助深搜来完成(有一点像记搜),并在回溯时 顺便 更新一下信息。
深搜通常分为以下几个步骤:
-
初始化
通常在dfs开头就进行初始化。 -
遍历出边
-
可行性剪枝
通常要判断下一个点不是父亲节点 -
继续深搜
-
更新信息
树形DP典例示范
题目描述:
现有一棵树,给出一个数\(x\),输出它子树的节点个数(包括\(x\)自己)
题目解析:
没什么好解析的了,都在代码里了
代码示范:
void dfs(int u, int father)
{
sz[u] = 1; // 初始化,刚开始子树大小就是1,即它本身
for (int i = h[u]; i; i = ne[i]) // 遍历出边
{
int j = e[i];
if (j == father) continue; // 可行性剪枝,判断父亲
dfs(j, u); // 继续深搜
sz[u] += sz[j]; // 统计答案
}
}
树形DP经典例题
[https://www.luogu.com.cn/problem/P2015](luogu 二叉苹果树)