题面
给定一棵树,点有点权,其中这棵树满足除了权值最小的点外,每个点都有一个权值比它小的点与它相邻。
要求你重新构建这棵树,使得代价最小。计算代价的方法如下:
现在规定:
- 一个点的代价为:\(\text{deg}_u \times a_u\),其中 \(\text{deg}_u\) 表示点 \(u\) 的度数,即与 \(u\) 直接相连的节点数。
- 一条边 \((u,v)\) 的代价为 \(\lceil \log_2 \text{dis}(u,v) \rceil \times \min(a_u,a_v)\),其中 \(\text{dis}(u,v)\) 为 \(u\) 和 \(v\) 在原树中的距离。
一棵树的代价为点的代价 + 边的代价。
保证原树中权值最小的点唯一。
\(n \le 5\times 10^5\)。
题解
生成树
最小生成树
图论
将贡献算到边权中:每条边贡献为 \(\lceil \log_2 \text{dis}(u,v) \rceil \times \min(a_u,a_v) + a_u + a_v\)。
以最小值节点为根,显然每个点只会向其祖先连边。
而代价的 \(\log\) 函数决定了只要向 \(2^k\) 祖先连边就是最优的,正确性可以通过调整法证明。
然后边数就是 \(\mathcal O(n \log n)\) 的了,如果要排序 Kruskal,那么就是 \(\mathcal O(n \log ^2 n)\)。但是我们可以在每个点处理出最佳的边,然后排序的 \(\log\) 就没有了。复杂度 \(\mathcal O(n \log n)\)。
启示
- 奇怪的贡献函数启示了要对应其进行分析;如果贡献函数过于复杂(比如这个题目的点和边的贡献),那么可以考虑简化成一个函数;如果贡献函数看起来比较奇特,那么可以想一想这个函数的性质是什么(决策单调性?是否有一些最优的决策点?)
- \(\mathcal O(n^2)\) 条边的最小生成树的一种优化方式就是考虑简化连边数量;另一种可以使用
Boruvka 算法
(“别乳卡”算法!)。