洛谷P3478 [POI2008]STA-Station(二次扫描和换根法)

题目传送门

换根 DP
树形 DP 中的换根 DP 问题又被称为二次扫描,通常不会指定根结点,并且根结点的变化会对一些值,例如子结点深度和、点权和等产生影响。
通常需要两次 DFS,第一次 DFS 预处理诸如深度,点权和之类的信息,在第二次 DFS 开始运行换根动态规划。(摘自OI Wiki)

题意:给定一个n个点的树,请求出一个结点,使得以这个结点为根时,所有结点的深度之和最大。

暴力做法:直接枚举每一个结点为根的情况,DFS求出最优解(时间复杂度为O(n2)

但题目中n的数据范围到达了106,O(n2)的算法是肯定过不了的,所以考虑优化

首先,枚举结点1~n的复杂度是肯定无法省略的 (不然还求个毛的最优解啊。。。)

那么考虑如何优化才能在更短的时间内求出每个结点的价值

可以思考一个问题:以结点i为根的树的深度之和与什么东西会产生联系盲猜一波肯定不是父结点就是子结点啊 啊不貌似这两个是等价的哎

所以顺着树型DP的思路,用f[x]表示以结点x为根时树的深度之和,尝试去寻找f[u]与f[v]之间的关系(v为u的子结点)

我们发现:可以把以v为根的这整棵树分为两部分,一部分(为了方便,我们把它称作p部分)是当u为v的父亲时以v为根的子树上的结点,另一部分(q部分)就是余下的所有结点(有点抽象?画个图理解下:)
在这里插入图片描述
当根结点从u变为v时,p部分的结点深度都减少了1,q部分都增加了1
所以我们可以考虑先用一遍DFS求出令结点x(随意取一个结点)为根时的最大深度,同时预处理出x为根时以每个结点i为根的子树的结点数量sum[i]
由上面的推导可以知道:f[v]=f[u]-sum[v] (p部分减少的总深度)+n-sum[v] (q部分增加的总深度,q部分的结点总数实际上就等于总的结点数减去p部分的结点数),
f[v]=f[u]+n-2*sum[v],再用一遍DFS即可求解
max(f[i]),i from 1 to n即为目标解

代码时间到~~~

#include<bits/stdc++.h>
using namespace std;
int num=1,head[1000005],n,ansx,now,sum
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值