将树分成相等的部分

时间:2011-11-24 18:27:06

标签: algorithm tree graph-theory split longest-path

我正在寻找一种算法,通过从中删除一个边缘来分割具有N个节点的树(其中每个节点的最大度数为3),从而使得作为结果的两棵树尽可能接近N / 2。如何找到“最集中”的边缘?

树来自算法的前一阶段的输入,并作为图形输入 - 因此它不平衡,也不清楚哪个节点是根。

我的想法是找到树中最长的路径,然后选择最长路径中间的边缘。它有效吗?

最理想的是,我正在寻找一种解决方案,可以确保这两棵树都没有超过2N / 3个节点。

感谢您的回答。

2 个答案:

答案 0 :(得分:7)

我不相信您的初始算法适用于我在评论中提到的原因。但是,我认为您可以使用修改后的DFS在O(n)时间和空间中解决此问题。

首先走图表来计算总节点数;叫这个现在,选择一个任意节点并将树根目录。我们现在将从根开始递归地探索树,并将为每个子树计算每个子树中有多少个节点。这可以使用简单的递归来完成:

  • 如果当前节点为null,则返回0.
  • 否则:
    • 对于每个孩子,计算以该子项为根的子树中的节点数。
    • 返回1 +所有子子树中的节点总数

此时,我们知道每个边缘通过移除边缘将得到什么分割,因为如果该边缘下面的子树中有k个节点,则溢出将是(k,n-k)。因此,您可以通过遍历所有节点并寻找最均衡(k,n - k)平衡的节点来找到最佳切割。

计算节点花费O(n)时间,并且运行递归访问每个节点和边缘最多O(1)次,因此也需要O(n)时间。对于O(n)的净运行时间,找到最佳切割需要额外的O(n)时间。由于我们需要存储子树节点计数,我们也需要O(n)内存。

希望这有帮助!

答案 1 :(得分:1)

如果你看到我对Divide-And-Conquer Algorithm for Trees的回答,你会发现我会找到一个节点,将树分成两个大小相等的树(自下而上的算法),现在你只需要选择其中一个边缘这个节点可以做你想做的事。

您当前的方法不起作用假设您有一个完整的二叉树,现在将一个长度为3*log n的路径添加到其中一个叶子(将其命名为bad leaf),您的最长路径将在一个内另一个叶子到连接到这个bad叶子的路径的末端,你的中间边缘将在这条路径内(实际上在你通过坏叶子之后)并且如果你在这个边缘上划分基础你有一部分O(log n)和另一部分O(n)