给定一棵含有
n
n
n个结点的树,把它分成若干条链(边只能选一次,点可以选多次),使得最短的那条链的长度最长是多少。
n
≤
1
0
5
n\leq 10^5
n≤105
S
o
l
\mathrm{Sol}
Sol
一道
S
T
L
STL
STL良(凉)好练习题。
我们首先肯定会去二分答案
L
L
L那个最长链长,关键是如何判定。
我们这边利用
m
u
l
t
i
s
e
t
multiset
multiset这个东东来维护,它是什么讷?就是一个容器,然后加入元素会帮你从小到大排序,且允许加入重复的元素,且删增操作是
l
o
g
log
log的。
然后我们就有考虑如何去判定:对于一个节点
u
u
u有若干条从
v
v
v连过来的边,我们尽量找道两条链
l
1
,
l
2
l1,l2
l1,l2连接使得
l
1
+
l
2
l1+l2
l1+l2尽量接近且大于等于
L
L
L。这个还是简单易懂的。于是我们是两两配对所以
u
u
u要从儿子节点
v
v
v连过来并且要有一条边给自己的父亲节点
f
u
f_u
fu,那么如果从儿子那儿有奇数条边那么就不管了,如果偶数条边,我们强制构造出奇数条边(即加入一条
0
0
0边)。
于是我们
O
(
n
log
2
n
)
O(n\log^2 n)
O(nlog2n)做完了这道题目,似乎还可以双指针优化到
O
(
n
log
n
)
O(n\log n)
O(nlogn),这儿不多加介绍(因为比较菜。