题目
题目链接
题解树状DP。
基础树状DP题了。
首先先讲一下题目什么意思(起初,我就理解错了)
题目说在树上找一些点,这些点满足:在这些点中任取两个点a
和b
,都能够找到一条路径连通。
我这样一翻译是不是感觉清晰多了,其实就是找一个点集,保证点击任意两点可达,这就是在找个连通区域。
(最开始,我理解成了要找一条直径使得直径上的点价值加起来最大……)
dp[i][0/1]
表示以i
为根的子树不选取根节点i
和选取根节点i
构成连通区域的最大分数;(比较难以描述) dp[i][0]
是不选根节点,意味着以i
为根节点的树的那些不包含i
的子树的最大分数为dp[i][0]
,这个连通区域要么是i
的左子树中,要么在右子树中,而每棵子树也包含两种状态,即含根与不含根,所以转移方程为:dp[i][0] = max(dp[i][0], dp[j][1], dp[j][0])
,其中j
为i
的子节点。 dp[i][1]
是选根节点,意味着这个连通区域一定要跨越i
,当然可以i
的某个子树中一个节点都不选,也可以选若干个,只要保证连通即可。遍历每个子结点j
,如果想要与i
构成连通区域,那么j
节点必须被选上,要是不选j
的话i
节点根本没法与以j
为根节点的子树部分相连通啊,当然,i
也可以选择不与j
的子树连通,对于这两种情况选个最大的得分加上,每个子节点都遍历完成,都加上了就算出了dp[i][1]
。所以转移方程为:dp[i][1] += max (0, dp[j][1])
注意开LL。
代码#include
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int e[N u >> v,
add (u, v),
add (v, u);
dfs (1, 0);
cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?