【暑假集训】之被ACM金牌大神虐的第三天之树形dp篇

【感想1】:嘛。。今天终于能把讲的内容稍微写下代码了。。。

Computer(HDU2196)

给出一个n个节点的树,求出到每个点最远的点到它的距离。
【思路】
1、直接从每个点出发搜索到他最远的那个点。总复杂度O(n^2)。
2、利用树的特殊性质,树形dp,复杂度 O(n)。
那么怎么dp呢?
我们以任意一点作为根把整棵树提起来。一个点到他最远的点只有两种可能:
1、这个点在它的子树内部。
2、这个点不在它的子树内部。
所以,我们要dp两次,每次分别解决其中一种情况。
我们设dp1[i]表示以i为根,最远点在子树内部的最远距离转移时,考虑一个点u,再考虑它的所有儿子vdp1[u]=max(dp1[v]+1)。如果这是一棵带权树,就加上相应的边权值w。dp1[u]=max(dp1[v]+w)
那么在子树外呢?
用dp2[i]表示第i个点到不在它子树内部点的最远距离。
这里也是只有两种情况:
1、这一点在它父亲的某一颗子树中。
2、这一点不在它父亲的子树中。
对于第一种情况:
考虑一个点u,和他的父亲fa。我们找到Fa所有儿子中的最大值mx和次大值mxx。如果dp1[u]=mx 则dp2[u]=w+mx,否则dp2[u]=w+mxx
对于第二种情况:
直接用fa的dp2值去转移
dp2[u]=dp2[fa]+1
两边dp跑完之后,每个点的答案就是
max(dp1,dp2)
【感想2】:今天大神终于直播打代码了。。。 大笑 大笑,然后迅速打完代码之后,迅速过了样例,然后迅速提交,卧槽,一次过啊有木有,由此得出,大神不愧是大神。。
【代码】:然而代码呢?。。。不好意思,还没写,只说能写而已

树的直径
树直径的定义为一棵树上距离最远的两个点之间的距离。
其实我们刚才的dp也顺便解决了这个问题,就是所有点答案的最大值。
求直径更常用的方法是在树上随便找一个点,做一遍bfs,求出到他最远的点。再任取一个到他最远的点,从这点出发,再做bfs,到这一点最远的距离就是直径。
House of Representatives(Gym 100496H)
给出一个有边权和点权的树,第i个点的权值为p[i]。
现在我们要选出一些点,选每个点都有对应的代价,
选出第i个点的代价为:

选出一个点,最小化代价
【思路】:
本题的解法和上一题类似,也是把代价分成两个部分。

dp1[i]表示选第i个点,只考虑i所在的子树,最小代价是多少。

sum[j]表示j这棵子树的权值和,wij为i到j的边权,j是i的所有儿子节点。
现在考虑第二种情况。

设u是v的父亲,我们考虑从u向v转移的过程:

1是根节点,j枚举u的所有儿子。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值