作者:H_D_NULL
题目链接:SP3912 MTREECOL - Color a tree
题意
给定一棵树以及每个结点的权值 v i v_i vi,要求对所有点进行染色,条件是这个点的父节点已被染色,根节点第一个染色。染色的代价为染到这个点的时间 T ∗ v i T* v_i T∗vi,要求合理选出一种染色顺序(不用输出),使染色的代价和最小。
(比如对于一棵退化成链的树 1 − > 2 − > 3 1->2->3 1−>2−>3,染色顺序确定为 1 − > 2 − > 3 1->2->3 1−>2−>3,代价总和为 1 × v 1 + 2 × v 2 + 3 × v 3 1\times v_1+2\times v_2+3\times v_3 1×v1+2×v2+3×v3)
思路
在树上求代价,首先考虑树形 DP ,但是因为染色顺序没有规律,会对 DP 产生后效性,故排除,那么找到这种问题最佳策略的方法大概率为贪心;
先思考如果没有树结构的限制,那么最优方案肯定是按权值从大到小的顺序选,所以很容易想到两个错误的贪心策略,以下是错误示范和hack:
- 在所有可染的结点中选择权值最大的。hack:可选一个较小的结点,子树中有很多大结点,另外可选一个稍大的结点,没有子树;
- 在所有结点中选择权值最大的。hack:可选一个较小的结点,子树中有一个很大的结点,但是深度巨大,子树中其他结点很小,另外可选一个比刚刚的大结点稍小的结点;
不难发现,以上两个解法的错误都是因为没有考虑树结构限制染色顺序,针对某个点的权值,进而无法保证按顺序贪心的代价最小。
到这里,肯定有人(大概不是你)会敏锐地发现:“那如果一个点的即是权值最大的,又是现在可选,那一定选它吧。”没错,由这个结论,我们又可以引出一个重要的结论:如果一个点的权值最大,那么它一定在其父节点之后紧接着被染色。
那么有人(就是你了)多半会问:“这样只能确定这两个点的染色顺序,那么如何确定其父节点的染色时间呢?”虽然暂时无法解决这个问题,但是这给我们提供了一个思路,及将两