hdu 4822 Tri-War
给定一棵无根树,边权都为1,每次询问给定三个点,求这三个点各控制了多少个点。
点A被点B控制当且仅当点A到其他点的的距离都小于点A到点B的距离。
这道题可以是一道大讨论题,但感觉很容易讨论错且找不到问题。所以想了一些更完备优美的做法。
三个点$x , y , z$确定以后,明显对于大部分点都是没有意义的,有意义的只有$x , y , z$之间的$LCA$,即最近公共祖先。为了避免麻烦,我将$x , y , z$间路径的中点也列入关键点,这个中点有可能有两个。
这样对于一个询问,就能把树简化为一个至多12个点的结构。利用树的dfs序列可以实现线性复杂度建树,当然这里暴力建树也没问题。
现在再考虑其他点,这些点分为两类,一部分点会附加到某个关键点上,另一部分点会附加到关键点之间的边上,每个关键点和边的权值都可以用子树的size容斥出来。最后就可以在这棵树上DFS出每个点/边被$x , y , z$哪个点控制。点权可能无法被控制,但边权肯定是要被一个点控制的。
这种做法也很容易扩展到每次询问给定$k$个点的情况,每次询问的时间复杂度都是$O(k)$级别的。
建立新树的关键代码: