【发布时间】:2010-10-26 01:48:34
【问题描述】:
我有一个问题,这是我的程序的一部分。
对于一棵树 T=(V,E),我们需要在树中找到节点 v,它使从 v 到任何其他节点的最长路径的长度最小。
那么我们如何找到树的中心呢?是否只能有一个或多个中心?
如果有人可以为此提供好的算法,我可以了解如何适应我的程序。
【问题讨论】:
标签: algorithm tree graph-theory
我有一个问题,这是我的程序的一部分。
对于一棵树 T=(V,E),我们需要在树中找到节点 v,它使从 v 到任何其他节点的最长路径的长度最小。
那么我们如何找到树的中心呢?是否只能有一个或多个中心?
如果有人可以为此提供好的算法,我可以了解如何适应我的程序。
【问题讨论】:
标签: algorithm tree graph-theory
有两种方法可以做到这一点(两者同时运行):
选择树上的任何顶点v1。从这个顶点运行BFS。您将进行的最后一个顶点 (v2) 将是距离 v1 最远的顶点。现在运行另一个 BFS,这次从顶点 v2 获取最后一个顶点 v3。
从v2 到v3 的路径是树的直径,而你的中心位于树的某个位置。更准确地说,它位于它的中间。如果路径有2n + 1 点,则只有1 个中心(在n + 1 位置)。如果路径有2n点,则n和n + 1位置会有两个中心。
您只使用了 2 个在 2 * O(V) 时间运行的 BFS 调用。
【讨论】:
v1 和v2 是否有一些共同的父级。你取任何顶点并取它的孩子。然后,使用 BFS 分别从他们的每个孩子开始找到最长的路径,并取两条最长的路径。最后,取从一片叶子到另一片叶子的路径的中点。
考虑一棵有两个节点的树?哪个是中心?任何一个都足够了,因此一棵树可以有多个中心。
现在,想想成为中心意味着什么。如果所有分支的高度相同,则中心是根(所有路径都经过根)。如果分支的高度不同,则中心必须是根或在具有最大高度的分支中,否则最大路径大于最高分支的高度,根将是更好的选择。现在,我们需要从最高的树枝往下看多远?最高分支(从根)和下一个最高分支之间高度差的一半(如果差异最多为 1,根就足够了)。为什么,因为当我们沿着最高的分支向下一级时,我们将到下一个最高分支的最深节点的路径加长了一级,并将到当前分支中最深节点的距离减少了一级。最终,当您穿过深度差异的一半时,它们将相等。现在,当我们沿着最高的分支走下去时,我们只需要在每一层选择最高的子分支。如果不止一个高度相同,我们就随意选择一个。
本质上,您所做的是在图中找到最长的路径,即树的最高分支与下一个最高分支之间的距离,然后找到该分支上的中间节点。因为可能存在多条与最长路径长度相同的路径,并且最长路径的长度可能是偶数,所以您有多个可能的中心。
【讨论】:
我不会为你做这个家庭作业问题,而是通过思考过程来询问你得到答案的过程......
1) 你会如何处理图 a-b-c(三个顶点,两条边,并且绝对是非循环的)?想象一下,您必须在某些顶点上放置一些标签,您知道您将在“中心”顶点上获得最长路径的最小值。 (b,最终标签为“1”)但一步完成需要精神力量。所以问问自己,离 b 有 1 步之遥。如果到 b 的最长路径是 1,而我们只是沿着那条路径向后退了一步,那么到目前为止我们的路径长度是多少? (最长路径 = 1,后退一步为 -1。啊哈:0)。所以那一定是叶子的标签。
2) 作为算法的第一次切割,这意味着什么?标记叶子“0”,标记它们的上游“1”,标记它们的上游“2”等等。从树叶中走进来,边走边数距离……
3) 嗯...我们的图 a-b-c-d 有问题。 (从现在开始,标记的顶点将被其标签替换。)标记叶子“0”给出0-bc-0......我们不能得到两个中心......哎呀,我们在更简单的情况下做什么条件 0-b-1?我们想用“1”和“2”来标记b……以相反的顺序处理它们……
在 0-b-1 中,如果我们将 b 左侧的路径延长 1,则得到长度为 1 的路径。如果将 b 右侧的路径延长,则得到 2。我们要跟踪“从 v 到任何其他节点的最长路径”,所以我们要跟踪到 b 的最长路径。这意味着我们将 b 标记为“2”。
0-b-1 -> 0-2-1
在 0-b-c-0 中,计算机实际上并没有同时更新 b 和 c。它更新其中一个,给出 0-1-c-0 或 0-b-1-0,下一次更新给出 0-1-2-0 或 0-2-1-0。 b 和 c 都是该图的“中心”,因为它们中的每一个都满足“树中的节点 v 最小化从 v 到任何其他节点的最长路径的长度”的需求。 (长度为 2。)
这导致另一个观察结果:计算的结果不是标记图,而是找到我们标记的最后一个顶点和/或以最大标签结束的顶点。 (有可能我们找不到订购标签的好方法,所以我们最终需要找到最后的最大值。或者也许我们会。谁知道呢。)
4) 所以现在我们有类似的东西:制作图表的两个副本——带标签的副本和烧毁的副本。第一个将存储标签,它将在其中包含最终答案。随着我们从中删除未标记的顶点(以找到新的可标记顶点),烧毁副本将变得越来越小。 (还有其他组织方法,以便只使用图表的一个副本。当您对这个答案的理解结束时,您应该找到一种减少这种浪费的方法。)大纲:
标签 = 0 而燃尽图是非空的 将燃尽图中的所有叶子收集到集合 X 中 对于集合 X 中的每个叶子 如果叶子没有标签 设置叶子的标签(标签的当前值) 从燃尽图中删除叶子(这些叶子是输入图中同一叶子的两个副本) 标签 = 标签+1 找到具有最大标签的顶点并将其返回5) 如果您实际观看此运行,您会发现一些走捷径的机会。包括将大纲最后一行的搜索替换为更快的方法来识别答案。
现在是算法问题的一般策略提示:
* 手工做几个小例子。如果你不明白如何做小案子,你不可能直接跳进去告诉计算机如何做大案子。
* 如果上述任何步骤似乎没有动力或完全不透明,您将需要更加努力地学习计算机科学。可能是计算机科学不适合你...
【讨论】: