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

例:UVA1205

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

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

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

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

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

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

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

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

posted @ 2020-11-30 22:18  andysj  阅读(102)  评论(0编辑  收藏  举报