我正在寻找一种算法,通过从中删除一个边缘来分割具有N个节点的树(其中每个节点的最大度数为3),从而使得作为结果的两棵树尽可能接近N / 2。如何找到“最集中”的边缘?
树来自算法的前一阶段的输入,并作为图形输入 - 因此它不平衡,也不清楚哪个节点是根。
我的想法是找到树中最长的路径,然后选择最长路径中间的边缘。它有效吗?
最理想的是,我正在寻找一种解决方案,可以确保这两棵树都没有超过2N / 3个节点。
感谢您的回答。
答案 0 :(得分:7)
我不相信您的初始算法适用于我在评论中提到的原因。但是,我认为您可以使用修改后的DFS在O(n)时间和空间中解决此问题。
首先走图表来计算总节点数;叫这个现在,选择一个任意节点并将树根目录。我们现在将从根开始递归地探索树,并将为每个子树计算每个子树中有多少个节点。这可以使用简单的递归来完成:
此时,我们知道每个边缘通过移除边缘将得到什么分割,因为如果该边缘下面的子树中有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)
。