poj2054 精品好题

这道题真的很好,非常有思想性,值得收藏。我想了好久,最后在别人文章的启发下才想了出来。而且就算想出了方法,要实现起来也不是那么容易。不过我还是一遍AC了嘿嘿。

 

题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2054

 

题意:有一棵有根树,每个节点有一个Ci值,对这些结点进行染色,一个节点可以被染色仅当他的父亲节点被染色,每个节点有一个染色时间Fi,最后让你求如何安排染色顺序使得sum{Ci * Fi}最小。

 

如果没有“一个节点可以被染色仅当他的父亲节点被染色”这个条件,那么就很简单了。只要每次先染c[i]最大的即可。但是加了这一条件了之后问题就复杂的多。核心想法是:所有节点中c[i]最大的那个节点的顺序必定跟在它父亲节点之后。感觉上这方法有点像kruscal式贪心算法,从不同位置突破,最后化而为一。而不像prim那种按照一定的顺序贪心。为什么这样做正确呢?因为假设在该点(记为x)和父节点(px)之间有其他元素(记为b1,b2,b3....),那么不可能是px的祖先,也不可能是x的祖先。所以交换x与b1的顺序,并不影响任何节点的可涂色性,同时也使总权重非增(想一想,为什么?)。依次类推,再和b2,b3交换,直到接在其父节点后面。理解了这个思想,实现这题就不难了。

你可能感兴趣的:(poj2054 精品好题)