写完这道题,跑了 372 ms。发现有一个跑了 12 ms 的,点进去一看,是
Θ(N) 做法。那么我们就来解释一下 kostia244 老师的做法。
假设树是
Γ=(V,E),以
r 为根,有分划
X⊔Y=V,且
Y 是一个独立集。假设
L 是全体叶子。我们可以直接通过式计算出
B,C:
B=∣Y∣−[r∈Y],C=2⋅Y∩L∁.
假设
r∈X。每一个
x∈Y∩L∁ 会强制其所有子节点
∈X。那么我们为了给出
B 的贡献,所强制的节点数是
f=v∈Y∩L∁∑(v 作为叶子的子结点数).
后文记这个
v 作为叶子的子结点数为
ℓ(v)。那么我们希望
B−2C 个叶子属于
Y,因此希望
f+B−2C≤∣L∣。如果
r∈Y,可以类似推理。
因此,我们的问题形式变为,求一个独立集
S⊆L∁,满足
∣S∣=K 且
v∈S∑ℓ(v)
最小。这个最小值我们记作
w(K)。处理其的一个方法是
Lagrange 松弛。由于如果我们直接放宽
∣S∣=K 的限制最小值会变成
0,所以我们考虑每选一个会使值额外减少
λ,也就是我们最小化
ℓ(v)−λ 的和,这时的问题记作
F(λ)。
现在我们说明,
λ 有用的取值只会有
[0,4]。这是因为:
λ<0 肯定还不如不选;而对于一个独立集
S,如果存在一个比
S 的元素个数更大的独立集,我们一定能够通过如下两种操作得到一个:
- 添加一个元素 x 到 S 中;
- 取 x∈S,设其两个儿子为 l,r,从 S 中删去 x 并添加 l,r。
无论哪种,答案的变化量不会超过
4。这样,你
ℓ(v)−λ 至少可以把
−4 的变化量变成
0。假设最优解
F∗(λ) 的
K 值为
K∗(λ),通过下述凸性,可以证明,
w(K) 可以通过:选取
λ 使得
K∗(λ)≥K 且
λ 最小,则
w(K)=F∗(λ)−λ⋅K。
下面,我们还要证明,
w 是凸的。我们采用线性规划的方法:对于每个点,赋实数
xu∈[0,1]。要求对于每一个
(u,v)∈E,
xu+xv≤1。并考虑
ℓ(v)xv 的求和。由 Birkhoff 定理得,有一个最大值满足
xk∈{0,1}。于是我们得到了一个线性规划问题:
P:x∈RV0≤x≤1xu+xv≤1 (uv∈E)∑x=Kminimizev∈V∑xv⋅cost(v).
我们可以得到这样的对偶问题。
P∨:∀v,λ≤cost(v)+∑yv?+svy≥0,s≥0,λ∈RmaximizeKλ−e∈E∑ye−v∈V∑sv.
s 取非
0 值对线性规划的限制紧,还会使欲最大化的值变小,因此毫无意义。取
s=0。则由于
P 可行且有界,
w(K)=val(P)=val(P∨)(强对偶定理)。可以发现
Kλ 一看就很像我们刚才提到的 Lagrange 松弛,因此考虑固定
λ 看盛夏的最优化问题。考虑对内层问题
I 作对偶(由于式过多略去),可以直观地感受到可行域恰好就是
x∈RV,0≤x≤1,xu+xv≤1 (uv∈E)(记为
H)。同时这个问题的权值可以通过计算得出等于
x∈Hminv∈V∑(cost(v)−λ)xv.
与 Lagrange 松弛恰好等价!
因此
w(K)=λ∈Rmax(F∗(λ)−λK),
也就是一族关于
K 的一次函数的
max,是凸的。这下,我们一并解决了为什么
w 是凸的,为什么 Lagrange 松弛是对的这两个问题。
上文提到,选取
λ 使得
K∗(λ)≥K 且
λ 最小,则
w(K)=F∗(λ)−λ⋅K。这根据上面的式子也是好解释的。而且
0≤λ≤4 使得我们只需要计算
F∗(λ) 五次。而每一次我们都可以简单地用树形 DP 计算。
至此,我们得到了一个时间复杂度为
Θ(N) 的算法。
参考代码可以看
kostia 的,有一些包括但不限于
λ↔−λ 的小差距。