为了找到树的直径,我可以从树中获取任何节点,执行BFS以找到距离它最远的节点,然后在该节点上执行BFS。与第二个BFS的最大距离将产生直径。
我不知道如何证明这一点?我尝试过对节点数量的归纳,但是有太多的情况。
任何想法都会受到赞赏......
答案 0 :(得分:15)
让我们调用第一个BFS x找到的端点。关键的一步是证明在第一步中找到的x始终“有效” - 也就是说,它始终位于某条最长路径的一端。 (请注意,通常可以有多个同样最长的路径。)如果我们可以建立这个,那么很容易看到以x为根的BFS会尽可能地从x找到一个节点,因此必须是整体最长的路径。
提示:假设(相反)两个顶点u和v之间存在较长的路径,两者都不是x。
观察到,在u和v之间的唯一路径上,必须有一些最高(最接近根)的顶点h。有两种可能性:h是从BFS根到x的路径上,或者不是。通过显示在两种情况下,u-v路径至少可以通过用x的路径替换其中的某个路径段来显示一个矛盾。
[编辑] 实际上,可能没有必要分别处理这2个案件。但我经常发现将配置分成几个(甚至很多)的情况更容易,并分别对待每一个。这里,h在从BFS根到x的路径上的情况更容易处理,并为另一种情况提供线索。
[编辑2] 稍后再回过头来看,现在我觉得需要考虑的两个案例是(i)uv路径与从根到x的路径相交(在某些顶点y,不一定在uv路径的最高点h); (ii)它没有。我们仍然需要h来证明每个案例。
答案 1 :(得分:7)
我要去锻炼j_random_hacker's hint。让s, t
成为最远的一对。设u
为任意顶点。我们有一个像
u
|
|
|
x
/ \
/ \
/ \
s t ,
其中x
是s, t, u
的交汇点(即位于这些顶点之间的三条路径中的每条路径上的唯一顶点)。
假设v
是距离u
最远的顶点。如果原理图现在看起来像
u
|
|
|
x v
/ \ /
/ *
/ \
s t ,
然后
d(s, t) = d(s, x) + d(x, t) <= d(s, x) + d(x, v) = d(s, v),
由于d(u, t) = d(u, x) + d(x, t)
和d(u, v) = d(u, x) + d(x, v)
,不等式成立。有一个对称的情况,v
和s
之间的x
附加,而不是x
和t
之间。
另一个案例看起来像是
u
|
*---v
|
x
/ \
/ \
/ \
s t .
现在,
d(u, s) <= d(u, v) <= d(u, x) + d(x, v)
d(u, t) <= d(u, v) <= d(u, x) + d(x, v)
d(s, t) = d(s, x) + d(x, t)
= d(u, s) + d(u, t) - 2 d(u, x)
<= 2 d(x, v)
2 d(s, t) <= d(s, t) + 2 d(x, v)
= d(s, x) + d(x, v) + d(v, x) + d(x, t)
= d(v, s) + d(v, t),
所以max(d(v, s), d(v, t)) >= d(s, t)
通过平均参数,v
属于最远距离对。
答案 2 :(得分:0)
这是另一种看待它的方法:
假设 G =( V , E )是一个非空的有限树,顶点集 V ,边集 E 。
考虑以下算法:
这基本上是从叶子向内着色图形,标记与绿色叶子最大距离的路径,并标记只有较短距离的红色路径。同时, C 的节点,与叶子的最大距离较短的中心将被削减,直到 C 仅包含一个或两个与叶子最大距离最大的节点。
通过构造,从叶顶点到仅遍历绿色边缘的最近中心顶点的所有简单路径都是相同的长度( count ),以及从叶顶点到其最近中心的所有其他简单路径顶点(遍历至少一个红色边缘)较短。此外可以证明
考虑到上述情况,现在考虑一下你的算法,这可能更实用。从任何顶点 v 开始,该顶点只有一条简单路径 p ,以中心顶点结束,并包含所有顶点center(因为 G 是一棵树,如果 C 中有两个顶点,那么它们共享一条边) 。可以证明,将 v 作为一个端点的 G 中的最大简单路径都具有 p ,从中心到叶子的路径只有绿色边缘。
我们目的的关键点是另一个端点的传入边缘必须是绿色。因此,当我们搜索从那里开始的最长路径时,我们可以访问从中心到另一个叶子的横向(所有顶点)的叶子遍历的绿色边缘。这些正是 G 中的最大长度简单路径,因此我们可以确信第二次搜索确实会显示图形直径。
答案 3 :(得分:0)
1:procedureTreeDiameter(T)
2:选择任意顶点v,其中v∈V
3:u = BFS(T,v)
4:t = BFS(T,u)
5:返回距离(u,t)
结果:复杂度= O(| V |)