动态编程帮助:二叉树成本边缘

时间:2012-02-17 09:28:22

标签: algorithm

给定一个带有n个叶子和一组C颜色的二叉树。树的每个叶节点被赋予来自集合C的唯一颜色。因此,没有叶节点具有相同的颜色。树的内部节点是未着色的。集合C中的每对颜色都有与之相关的成本。因此,如果树边连接颜色A和B的两个节点,则边缘成本是该对的成本(A,B)。我们的目标是为树的内部节点提供颜色,最小化树的总边缘成本。

我已经解决了这个问题好几个小时了,并没有真正想出一个有效的解决方案。任何提示都将不胜感激。

2 个答案:

答案 0 :(得分:2)

我将用伪代码来解决问题,因为我尝试编写解释,即使对我来说也完全不可理解。希望代码可以解决问题。我的解决方案的复杂性不是很好 - 在O(C ^ 2 * N)中记忆一个druntime。

我将需要几个数组,我将在动态方法中使用你的任务:
dp [N][C][C] - > dp[i][j][k]您可以从以节点i为根的树获得的最高价格,如果您使用颜色j进行绘制并且其父颜色为彩色k maxPrice[N][C] - > maxPrice[i][j]如果其父级颜色为i,则可以从植根于节点j的树中获得最高价格color[leaf] leaf - >叶子的颜色price[C][C]
price[i][j] - > i如果你有一对颜色为jchosenColor[N][C]的相邻节点,你会得到的价格 chosenColor[i][j] - > i应为节点maxPrice[i][j]选择的颜色inner_nodes

让我们假设节点是使用topological sorting排序的,即我们将处理第一片叶子。在树中很容易进行拓扑排序。让排序给出一个内部节点列表for leaf in leaves: for i in 0..MAX_C, j in 0..MAX_C dp[leaf][i][j] = (i != color[leaf]) ? 0 : price[i][j] for i in 0..MAX_C, maxPrice[leaf][i] = price[color[leaf]][i] chosenColor[leaf][i] = color[leaf] for node in inner_nodes for i in 0..MAX_C, j in 0..MAX_C dp[node][i][j] = (i != root) ? price[i][j] : 0 for descendant in node.descendants dp[node][i][j] += maxPrice[descendant][i] for i in 0...MAX_C for j in 0...MAX_C if maxPrice[node][i] < dp[node][j][i] maxPrice[node][i] = dp[node][j][i] chosenColor[node][i] = j for node in inner_nodes (reversed) color[node] = (node == root) ? chosenColor[node][0] : chosenColor[node][color[parent[node]]

{{1}}

答案 1 :(得分:1)

作为一个起点,您可以使用贪婪的解决方案,为您提供总成本的上限:

while the root is not colored
    pick an uncolored node having colored descendants only
        choose the color that minimizes the total cost to its descendants