树形动态规划之树的最大独立集

树的最大独立集

对于一颗n个结点的无根树,选出尽量多的的结点,使得任何两个结点均不相邻(称为最大独立集),然后输入n-1条无向边,输出一个最大独立集(如果有多解,则任意输出一组)。

分析:

用d(i)表示以i为根结点的子树的最大独立集的大小。此时需要注意的是,本题的树是无根的:没有所谓的父子关系,而只是一些无向边。没关系,只要任选一个跟r,无根树就变成了有根树,上述状态的定义也就有意义了。

结点i只有两种决策,选和不选。如果不选i,则问题转化为求出i所有的儿子的d值再相加;若选i,则它的儿子全部不能选,问题转化为了求出i的所有孙子的d值之和。换句话说,状态转移方程为:

d(i)=max{1+Ed(j)(j属于gs(i)),Ed(j)(j属于s(i))}

其中gs(i)和s(i)分别代表i的孙子集合和儿子集合。

代码应该如何编写呢?上面的方程涉及“枚举结点i的所有儿子和孙子结点”,颇为不便。其实可以换另一个角度来看:不从i找s(i)和gs(i)的元素,而从s(i)和gs(i)的元素找i。换句话说,当计算出一个d(i)后,用它去更新i的父亲和祖父结点的累加值Ed(j)(j属于gs(i)和Ed(j)(j属于s(i))。这样一来,每个结点不必记录其子结点有哪些,只需记录父结点即可。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值