对于一类树上依赖问题的理解

最近做了两道题目,都是类似于对于一棵树,给出一个排列,在排列上进行相应的操作,最大化计算出的答案。然后要求一个点的父节点在排列中要在它的前面。

如果没有树上的依赖,这个问题还是比较好解决的。那么我们先排出一个最优顺序。考虑对于一个最优点(x),如果它的父节点在它的前面,那么就直接把它选了就好了。否则就会在选择它的父节点后,立即将它选择。

那么我们就可以把(x)和它的父节点“捆绑”在一起,也就是把(x)(f_x)合并成一个新的点,这个点按照(f_x ightarrow{x})的顺序包含了这两个点。而新的这个点的有关值是原来两个点的值的和。如果把这个新的点代替原来两个点,重新建树, 那么新问题和原问题是等价的。

因此只需要不断重复这个操作,直到所有点都合并成一个点即可。

如何算答案呢?我们在找到一个点(x)和它的(f_x)后,假定一棵树只有两个点(x ightarrow{f_x}),相应的算出对答案的贡献,累加即可。

一定要注意原本的(f_x)和并查集的(fa_x)不是一个东西,不要弄混了。

找节点父子关系可以使用并查集维护,找最小值可以用堆维护。

时间复杂度:(O(nlog{n}))

原文地址:https://www.cnblogs.com/andysj/p/14064159.html