[NOIP2018]赛道修建
闲来无事,特意回味一下去年担当NOIPD1T3 (防AK却没能防住) 之大任的经典好题。 首先看到什么“最短赛道的长度尽可能大”,就知道离不开二分。于是我们想到了一种思路:二分+树上贪心。 二分判定很简单,就是对于二分出来的答案mid,检查树上是否有大于m条不相交的,权值和大于mid的链。而如何凑出尽可能多的权值和大于mid的链并使得它们互不相交,成为了这道题的关键之处。 树上贪心。 贪心策略不是很容易设计,下面给出一种:据题意可知,赛道的构建方式有且只有两种,1)一条链直接作为赛道(如下图中类似于红色的构建方式),2)两条半链(半链的理解对于这个题十分重要,请务必好好理解!)拼成一个赛道(因为不能走回头路因此最多只能两条拼)。我们对于以i为根的子树,先尽可能多的拼出赛道,同时在剩下拼不成整条赛道的情况下,选尽量长的传给父节点,作为父节点半链的候选答案。 根据题意及描述以及样例,易得这是一棵树,我们可以把1号节点作为根,从它开始进行搜索,对于每一个节点i,按照上面的贪心策略进行处理。 同时我们又会遇到一个问题:如何处理半链的拼接呢?显然,当子节点的最优长度加上本条边的长度>=Mid时,直接拼就可以了,如果不能的话,就把它放到multiset中进行维护,二分寻找最短的与当前长度的半链可以拼成整链的半链,如果找不到就打擂台取最大值,把最大的传上去即可。之后我们就可以开心地玩STL了~~