题意:一棵$n$个点,边带权的树,$m$次询问,每次给出k个关键点,求割掉最小代价的边使1号点不能到达任何关键点。
很裸的树形dp。但是数据范围太大了,承担不起$O(nm)$的复杂度。
这个时候就需要考虑虚树了。
什么是虚树?sengxian的博客讲得很好,这里就不多说了。
这是我的第一道虚树题。通过这道题也能看出很多细节。虚树的复杂度是时刻都必须要算准、保证好的。经常因为一些数组的初始化等问题使得复杂度直接回到了$O(nm)$。比如虚树的邻接表head数组初始化必须要记时间戳,将当前要用的点head清0,而不能直接调用memset。又比如这道题的dp决策,关键点和非关键点的决策是不同的。那么我们如何记录一个点是不是关键点?开数组的话显然初始化又成了问题。
对于这道题,我们发现在一个关键点下方的关键点dp值是没有任何意义的。所以我们在建虚树的时候就要首先预处理去掉这一类点。这样建出的虚树中关键点均为叶子,于是就不用担心什么了。
还有一点,建出虚树后的一条边等于原图的一条路径,那么边权怎么办?这道题中我们可以规避这个问题。令$mine[u]$为u到1号点路径中最小的边权,仅仅利用这个东西我们就能进行dp了。