IOI 2003:如何计算树中具有最小余额的节点?

时间:2011-05-25 12:34:32

标签: algorithm graph tree

这是Balancing Act问题,需要找到树中具有最小余额的节点。余额定义为:

  

删除任何节点   从树中产生一个森林:一个或多个树的集合。将节点的 balance 定义为通过从T

删除该节点而创建的林T中最大树的大小

对于样本树,例如:

  

2 6
1 2
1 4
4 5
3 7
3 1

说明是:

  

删除节点4会生成两个树,其成员节点为{5}和{1,2,3,6,7}。该   这两棵树中较大的一个有五个节点,因此节点4的余额为五。删除节点   1产生一个相同大小的三棵树的森林:{2,6},{3,7}和{4,5}。这些树中的每一个   有两个节点,所以节点1的余额是两个。

你可以为这个问题提供什么样的算法?

由于

2 个答案:

答案 0 :(得分:1)

我将假设您已经对这个问题进行了宽松的观察:阅读解决方案并没有帮助,只有通过解决这些问题才能更好地解决这些问题自己

所以需要注意的一点是,输入是一棵树。这意味着每条边将2棵较小的树连在一起。删除边缘会产生2个断开连接的树(2棵树林)。

因此,如果您计算边缘一侧树的大小,然后另一侧计算树的大小,您应该能够查看节点的边缘并询问“另一侧树的大小是多少”这边缘?“

你可以使用动态编程来计算树木的大小 - 你的重现状态是“我在哪个边缘?我的边缘的哪一边?”并计算该节点“挂”树的大小。这就是问题的症结所在。

拥有这些数据后,遍历所有节点就足够了,看看它们的边缘并询问“这条边的另一边树的大小是多少?”从那里,你只需选择最低限度。

希望有所帮助。

答案 1 :(得分:0)

您基本上想要检查每个节点的3件事情:

  1. 左子树的大小。
  2. 右子树的大小。
  3. 树的其余部分的大小。 (树的大小 - 左 - 右)
  4. 您可以使用此算法将其扩展为任何类型的树(不同数量的子节点)。

    in-order sequence中浏览树。

    递归地执行此操作:

    每次从节点备份到“父”节点之前,需要将1 +大小的节点总子树添加到“父”节点。
    然后存储一个值,我们称之为 maxTree ,在所有子树之间保持最大值的节点和(所有子树的总和) - (树的大小)。

    这样您就可以在 O(N) 中计算所有子树大小。
    在遍历树时,您可以保存一个包含到目前为止找到的最小值的变量。