为了找到一棵树的直径,我可以从树中任选一个节点,执行 BFS 查找距离该节点最远的节点,然后对该节点执行 BFS。第二次 BFS 的最大距离将得出树的直径。
不过我不确定如何证明这个算法的正确性?我已经尝试使用节点数量归纳,但有太多情况需要考虑。
非常感谢任何想法...
不过我不确定如何证明这个算法的正确性?我已经尝试使用节点数量归纳,但有太多情况需要考虑。
非常感谢任何想法...
我将处理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)
,其中 x
是在路径上连接 s
和 t
的节点。还有一种对称的情况,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),
v
属于最大距离对,因此 max(d(v, s), d(v, t)) >= d(s, t)
。这里有一种替代的看法:
假设G = (V, E) 是一个非空、有限的树,其中顶点集为V,边集为E。
考虑以下算法:
1:procedureTreeDiameter(T)
2:选择任意一个顶点v,其中v∈V
3:u = BFS ( T, v )
4:t = BFS ( T, u )
5:返回 distance ( u, t )
结果:复杂度为 O(|V|)