前言
这个东西据说(听师兄说)是这次
CSP−S 最后一题的题解做法,虽然还没去钻研那题,但是姑且算是把这个东西学会了。
思路
首先这是个在树上用的东西,一般就是不告诉你哪个点作为根,而你就需要求出所有点作为根时的答案,然后才能得到最终的答案。
思路也不是什么很神奇的东西:就是一开始先固定一个点作为根,然后
dp 一次求出解,然后利用这个解再做一次
dp——这次
dp 我们称为换根,这次
dp 求出其他点作为根时的解。
例题
例1
给出一棵有
n 个点的树,设
sum[x] 表示
x 到其他点的距离之和,要求出
∑i=1nsum[i]。
这个就是一个换根
dp 的入门题了,我们先随便固定一个点作为根,设这个点为
x,然后
O(n) 求出
sum[x],然后开始换根,考虑对于
x 而言,如何求出他的一个儿子
y 的
sum。
我们发现,树中点此时一共有两类:1、 在
y 的子树内的点;2、 不在y的子树内的点。
对于第一类点,他们到
y 的距离之和就是
sum[y]。
对于第二类点,他们到
y 的距离其实就是到
x 的距离再加上
len(x,y)。(
len(x,y) 表示
x 到
y 的那条边的长度。)
设
size[x] 表示以
x 为根的子树大小,那么很容易可以知道,第二类点一共有
size[x]−size[y] 个。所以第二类点到
y 的距离之和就是
sum[x]−sum[y]+(n−size[y])×len(x,y)−size[y]×len(x,y)。
加起来就是
sum[y]=sum[x]+(n−2×size[y])×len(x,y)。
例2 & 例3
(难度应该是递增的)
TJOI 2017 城市 题解
APIO 2014 连珠线 题解