请建议一些算法来查找树中的节点,该节点与所有节点之间的最远节点的距离最小

时间:2010-02-25 11:14:31

标签: c++ algorithm data-structures

请建议一些算法来查找树中节点,其距离最远节点的距离在所有节点中最小。

它不是图表,也没有加权。

5 个答案:

答案 0 :(得分:10)

在树 T 中选择任意节点 v 。 运行BFS,将 v 作为 T 的根目录。 BFS输出 v T 的所有其他节点的距离。

现在选择距离 v 最远的节点 u 。 再次运行BFS,将 u 作为根。 在新的距离输出上,找到距离 u 最远的节点 w

考虑 u w 之间的路径。 这是树 T 中最长的路径。 路径中间的节点<树> T 中心

请注意,树中可能存在两个中心。如果是这样,他们就是邻居。

性能: O(n),其中 n T 的节点数。

证明

声明:离某些节点 v 最远的一片叶子( u )位于最长的路径上

如果我们证明它,那么算法是正确的,因为它首先找到 u ,并且,因为它是最长路径的一端,所以使用DFS自己找到这条路径。

声明的证明:让我们使用retucto ad absurdum。假设 u --- r 是树中最长的路径;对于某些节点 v 既不 v --- u ,也 v --- r v 的最长路径。相反,最长的路径是 v --- k 。我们有两个案例:

a) u --- r v - k 有一个公共节点 o 。然后 v - o - u v - o - r u --- o --- k 短。然后 o --- r o --- k 短。那么 u --- o --- r 不是图中最长的路径,因为 u --- o --- k 更长。这与我们的假设相矛盾。

b) u --- r v - k 没有公共节点。但是,由于图形已连接,因此每条路径上都有 o1 o2 节点,因此它们之间的路径 o1 - o2 在这两个路径上不包含任何其他节点。与假设的矛盾与a)中的相同,但是使用 o1 - o2 而不仅仅是 o (事实上,指向 a >只是 b 的一个特例,其中 o1 = o2 )。

这证明了声明,因此证明了算法的正确性。

(这是由Pavel Shved撰写的证明,原作者可能会更短。)

答案 1 :(得分:3)

删除树叶。如果剩下2个以上的节点,请重复。剩下的节点(或2个节点)将是您要查找的节点。

为什么会这样:

节点位于树中最长路径P的中间。它们到任何节点的最大距离最多是路径长度的一半(否则它不会是最长的)。 P上的任何其他节点显然距离P的更远端的距离比找到的节点更远。不在n上的任何节点P将至少具有其最远的节点(距nP上最近的节点的距离,比如说c)+(距离从cP的更远端,所以再次比算法找到的节点更多。

答案 2 :(得分:1)

您可以依次在每个节点上使用Dijkstra算法(http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)来查找从该节点到每个其他节点的所有距离;扫描结果列表以获得到最远节点的距离。一旦你Dijkstra'd每个节点,另一次扫描将给你最小的最大距离。

Dijkstra通常被视为具有运行时O(v^2),其中v是节点数;你将在每个节点运行一次,这将在一个简单的实现中增加O(v^3)的时间。您可以通过存储早期节点的Dijkstra运行结果并在以后的运行中将它们用作已知值来获得收益。

答案 3 :(得分:1)

您可以将Johnson's algorithm用于稀疏图,但只能使用Floyd-Warshall algorithm,因为它实现起来很简单。

基本上你想要找到从每个节点到每个其他节点的距离,然后只是简单地搜索你想要的属性。

答案 4 :(得分:0)

其他人在评论中说: 树是一个图 - 准确无关的非连通非图 - 见"Tree" (Graph theory)

相关问题