我正在尝试编写一种树形分治算法。对于分割步骤,我需要一种算法来通过删除一个节点将给定的无向图G=(V,E)(具有n个节点和m条边)划分为子树。所有子图都应该具有以下属性:它们不包含超过n/2个节点(树应尽可能平均地分裂)。首先,我尝试递归地从树中删除所有叶子节点以找到最后剩下的节点,然后我尝试查找G中最长的路径并删除其中间节点。下面给出的图表明这两种方法都不起作用:
这里是我使用和测试过的一个方法。
从找到树的根节点开始,可以通过创建一个包含所有节点的集合并创建另一个数组NeighboursNumber[],其中存储每个节点的邻居数目对应的索引来完成。然后遍历这个集合并消除叶子节点(即具有NeighboursNumber[i] == 1的节点),确保将这些节点添加到另一个集合RemovedSet中(以避免更新问题),然后在每次迭代之后遍历RemovedSet并减少每个集合元素的所有邻居的NeighboursNumber[]条目。这种方法在拥有10^5个节点的树上仅需不到一秒钟。
这个问题似乎类似于寻找一个物体的质心。
假设每个节点都是等质量(重量)的点质量,并且其位置由图中给定。您的算法尝试查找质心,即在所有连接的子树中具有类似节点累积权重的节点。
您可以计算每个节点上所有子树的累积权重。然后选择最平衡的那个,即没有子树的权重超过n / 2
。这可能是一项动态规划任务。
H
,你会得到 9 个子树! - Shahbaz