树形dp专题

来源:互联网 发布:能看回放的网络电视 编辑:程序博客网 时间:2024/06/04 19:52

1.cf 804 C
最大团染色+dfs
题目中有个条件,相同的冰淇淋所在的节点是连通的,这个很重要
那么我们就对这个树T进行dfs,同时给G染色就行了
最大团染色xjb写
代码

2.xidian 1070
树形dp
dp[i][j]表示以i为根选j个节点的最大值
注意:类似于01背包那样逆推,就不会重复选择相同的子树了
代码

3.AtCoder Grand Contest 012 B

树形dp
1)暴力dfs
保存每一个顶点连同的顶点。
每一次输入v,d,c,搜索v节点的d范围内能够染色的点,每一次d-1;
然后你会发现完美的超时了

2)dp
dp[i][d]表示当前i节点d距离时的颜色,所以dp[i][0]为i节点的颜色,
所以就可以在dfs时判断如果当前节点dp[i][d]已经染了色,就可以不用染色了。
还有的就是:因为颜色是覆盖的,所以最后染的颜色就是结束的颜色。所以我们应该从后往前开始染色。
这样就可以保证,如果这节点d[i][0]染了色,就不会被覆盖了。
复杂度O(n*d)
代码

3)优化dfs
反过来做,染色过的点就不再染色
对于点u来说,如果以它为中心,距离为d的所有点都被染色过,那么下次你要对u距离为d’ (d’<=d) 的点染色时就可以直接退出了
复杂度O(n)
代码

4.poj1947
题意:
给一棵树,问最少删掉几条边.使得剩下的子树中有节点个数为p个。

思路:

    正过来想删多少边不好想,可以反过来思考保留多少节点      f(i, j) 表示子树i,保留j个节点的最少删边次数, 注意,这里保留的j个节点的子树,是指根节点    为i的且有j个节点的子树.这样理解的话, 状态转移就容易想多了.    对于子树i, 如果只保留1个节点,那么连接它所有儿子节点的边都要删掉,    所以可以初始化 f(i, 1) = 节点i的儿子个数    f(i, j), 即子树i保留j个节点, 那么对于i的每个子树,可以选择保留1,2,..j-1个节点    那么每个子树可以看作是一组物品,对所有子树做分组背包    子树v选择保留k个点的话,那么子树i就要保留j-k个点.    所以由状态转移:    f(i, j) = max{ max{f(i,j-k) + f(v, k) - 1 | 1<=k<s} | v是i的儿子节点 }    最终ans = min{ f(i, p)  |  1<=i<=n }

代码

0 0