简体   繁体   English

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

[英]Please suggest some algorithm to find the node in a tree whose distance to its farthest node is minimum among all the nodes

Please suggest some algorithm to find the node in a tree whose distance to its farthest node is minimum among all the nodes. 请建议一些算法来查找树中的节点,该节点与所有节点之间的最远节点的距离最小。

Its is not a graph and it is not weighted. 它不是图表,也没有加权。

Choose an arbitrary node v in the tree T . 在树T中选择任意节点v Run BFS making v as the root of T . 运行BFS使v成为T的根。 BFS outputs the distances from v to all the other nodes of T . BFS输出从vT的所有其他节点的距离。

Now choose a node u that is farthest from v . 现在选择距离v最远的节点u Run again BFS making u as the root. 再次运行BFS使成为root。 On the new distance output, find a node w that is farthest from u . 在新的距离输出上,找到距离u最远的节点w

Consider the path between u and w . 考虑uw之间的路径。 This is the longest path in the tree T . 这是树T中最长的路径。 The node in the midle of the path is the center of the tree T . 路径中间的节点是树T 的中心

Note that there may exist two centers in a tree. 请注意,树中可能存在两个中心。 If so, they are neighbours. 如果是这样,他们就是邻居。

Performance: O(n) , where n is the number of nodes of T . 性能: O(n) ,其中nT的节点数。

Proof 证明

Claim : a leaf ( u ) that is furthest from some node v lies on the longest path. 声明 :距离某个节点v最远的叶子( u )位于最长的路径上。

If we prove it, then the algorithm is correct, since it first finds u , and, since it's one end of the longest path, uses DFS to find this path itself. 如果我们证明它,那么算法是正确的,因为它首先找到 ,并且,因为它是最长路径的一端,所以使用DFS来找到这条路径本身。

Proof of the claim : Let's use retucto ad absurdum. 索赔的证明:让我们用retucto归谬法。 Assume u---r is the longest path in the tree; 假设u --- r是树中最长的路径; and for some node v neither v---u , nor v---r is the longest path from v . 而对于一些节点U既不v --- U,也不v --- r是从V的最长路径。 Instead, the longest path is v---k . 相反,最长的路径是v --- k We have two cases: 我们有两种情况:

a) u---r and v--k have a common node o . a) u --- rv - k有一个共同的节点o Then v--o--u and v--o--r are shorter than u---o---k . 然后v - o - uv - o - ru --- o --- k短。 Then o---r is shorter than o---k . 然后o --- ro --- k短。 Then u---o---r is not the longest path in graph, because u---o---k is longer. 然后u --- o --- r不是图中最长的路径,因为u --- o --- k更长。 It contradicts our assumption. 这与我们的假设相矛盾。

b) u---r and v--k don't have common nodes. b) u --- rv - k没有共同的节点。 But since the graph is connected, there are nodes o1 and o2 on each of these paths, such that the path between them o1--o2 doesn't contain any other nodes on these two paths. 但是,由于图形是连接的,因此在每个路径上都有节点o1o2 ,因此它们之间的路径o1-o2不包含这两个路径上的任何其他节点。 The contradiction to the assumption is the same as in point a), but with o1--o2 instead of mere o (in fact, point a is just a special case of b , where o1=o2 ). 与假设的矛盾与a)中的相同,但是使用o1-o2而不仅仅是o (事实上​​, a点只是b的一个特例,其中o1 = o2 )。

This proves the claim and hence the correctness of the algorithm. 这证明了索赔,因此证明了算法的正确性。

(this is proof written by Pavel Shved , and the original author might have a shorter one). (这是Pavel Shved写的证明,原作者可能会更短)。

Remove leaves. 去掉叶子。 If more than 2 nodes left, repeat. 如果剩下2个以上的节点,请重复。 The node (or 2 nodes) left will be the node you are looking for. 剩下的节点(或2个节点)将是您要查找的节点。

Why this works: 为什么这样有效:

The node(s) are in the middle of the longest path P in the tree. 节点位于树中最长路径P的中间。 Their max distance to any node is at most half of the length of the path (otherwise it would not be the longest one). 它们到任何节点的最大距离最多是路径长度的一半(否则它不会是最长的)。 Any other node on P will obviously have greater distance to the further end of P than the found node(s). P上的任何其他节点显然比找到的节点具有到P的另一端的更大距离。 Any node n not on P will have its furthest node at least (distance from n to the closest node on P , say c ) + (distance from c to the further end of P ), so again more than the node(s) found by the algorithm. 不在P上的任何节点n将至少具有其最远节点(从nP上最近节点的距离,比如c )+(从cP的另一端的距离),所以再次比找到的节点多通过算法。

You could use Dijkstra's algorithm ( http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm ) on each node in turn, to find all the distances from that node to every other node; 您可以依次在每个节点上使用Dijkstra算法( http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm )来查找从该节点到每个其他节点的所有距离; scan the resulting list to get the distance to the farthest node. 扫描结果列表以获得到最远节点的距离。 Once you've Dijkstra'd every node, another scan will give you the minimum of that maximal distances. 一旦你对每个节点进行了Dijkstra,另一次扫描就会给你最小的最大距离。

Dijkstra is usually regarded as having runtime O(v^2) , where v is the number of nodes; Dijkstra通常被认为具有运行时O(v^2) ,其中v是节点数; you'd be running it once per node, which will increase the time to O(v^3) in a naive implementation. 你将每个节点运行一次,这将在一个简单的实现中增加到O(v^3)的时间。 You may be able to make gains by storing the results of earlier nodes' Dijkstra runs and using them as known values in later runs. 您可以通过存储早期节点的Dijkstra运行的结果并在以后的运行中将它们用作已知值来获得收益。

You can use Johnson's algorithm for sparse graphs, but otherwise use the Floyd-Warshall algorithm simply because it is trivial to implement. 您可以将Johnson的算法用于稀疏图,但是否则使用Floyd-Warshall算法只是因为它实现起来很简单。

Essentially you want to find the distance from every node to every other node, and then just trivially search for the property you want. 基本上你想要找到从每个节点到每个其他节点的距离,然后只是简单地搜索你想要的属性。

正如其他人在评论中所说:树是一个图 - 一个确切的无向连通非循环图 - 见“树”(图论)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM