DFS/BFS求解的正确性分析
首先我们来看算法过程:
- 从树上任取一点 u u u,使用DFS/BFS找到离该点最远的点,即直径的端点之一 s s s
- 再对 s s s使用一次DFS/BFS,求得直径的另一端点 t t t
我们可以从反证法证明算法的正确性,首先证明距任意点最远的点一定是直径的端点之一。一颗树的直径是客观存在的,我们不妨就设树的直径为 s ⟶ t s\longrightarrow t s⟶t,任取一点 u u u,假设我们通过DFS/BFS求得的最远点为 v v v,那么会有两种情况:
- v v v为直径 s ⟶ t s\longrightarrow t s⟶t上(除去 s s s、 t t t)一点
- v v v为直径 s ⟶ t s\longrightarrow t s⟶t外一点
对于第一种情况,我们画图说明。
显然 v v v并不是 u u u的最远点,原因是 m a x { d i s t ( s , v ) , d i s t ( v , t ) } + d i s t ( u , v ) > d i s t ( u , v ) max\{dist(s,v),dist(v,t)\}+dist(u,v)>dist(u,v) max{dist(s,v),dist(v,t)}+dist(u,v)>dist(u,v),与我们 v v v距 s s s最远的前提相矛盾。
对于第二种情况,我们还可以将其分为两种情况:
- s ⟶ t s\longrightarrow t s⟶t和 u ⟶ v u\longrightarrow v u⟶v相交
- s ⟶ t s\longrightarrow t s⟶t和 u ⟶ v u\longrightarrow v u⟶v不相交
对于相交的情况,我们设相交的节点为 x x x(你也可以更严谨的认为是两条路径重叠部分的任意一点),画图说明。
此时有
∵
d
i
s
t
(
u
,
v
)
>
d
i
s
t
(
u
,
t
)
(1)
\because dist(u,v)>dist(u,t) \tag{1}
∵dist(u,v)>dist(u,t)(1)
∴
d
i
s
t
(
u
,
x
)
+
d
i
s
t
(
x
,
v
)
>
d
i
s
t
(
u
,
x
)
+
d
i
s
t
(
x
,
t
)
∴
d
i
s
t
(
x
,
v
)
>
d
i
s
t
(
x
,
t
)
∴
d
i
s
t
(
s
,
x
)
+
d
i
s
t
(
x
,
v
)
>
d
i
s
t
(
s
,
x
)
+
d
i
s
t
(
x
,
t
)
∴
d
i
s
t
(
s
,
v
)
>
d
i
s
t
(
s
,
t
)
(2)
\begin{aligned} \therefore dist(u,x)+dist(x,v)&>dist(u,x)+dist(x,t) \\ \therefore dist(x,v)&>dist(x,t) \\ \therefore dist(s,x)+dist(x,v)&>dist(s,x)+dist(x,t) \\ \therefore dist(s,v)&>dist(s,t) \tag{2} \end{aligned}
∴dist(u,x)+dist(x,v)∴dist(x,v)∴dist(s,x)+dist(x,v)∴dist(s,v)>dist(u,x)+dist(x,t)>dist(x,t)>dist(s,x)+dist(x,t)>dist(s,t)(2)
显然矛盾。
由于 v v v是 u u u找到的最远点,显然有 ( 1 ) (1) (1)
( 2 ) (2) (2)与前提矛盾
对于不相交的情况,我们画图说明。
这种情况下 s ⟶ t s\longrightarrow t s⟶t和 u ⟶ v u\longrightarrow v u⟶v互不相交,但由于图是树,一定存在 u ⟶ t u\longrightarrow t u⟶t,我们设这条路在 x x x点(可以)离开 u ⟶ v u\longrightarrow v u⟶v,在 y y y点进入 s ⟶ t s\longrightarrow t s⟶t,画图说明。
此时有
∵
d
i
s
t
(
u
,
v
)
>
d
i
s
t
(
u
,
t
)
∴
d
i
s
t
(
u
,
x
)
+
d
i
s
t
(
x
,
v
)
>
d
i
s
t
(
u
,
x
)
+
d
i
s
t
(
x
,
y
)
+
d
i
s
t
(
y
,
t
)
∴
d
i
s
t
(
x
,
v
)
>
d
i
s
t
(
x
,
y
)
+
d
i
s
t
(
y
,
t
)
∴
d
i
s
t
(
x
,
v
)
+
d
i
s
t
(
x
,
y
)
+
d
i
s
t
(
s
,
y
)
>
2
∗
d
i
s
t
(
x
,
y
)
+
d
i
s
t
(
y
,
t
)
+
d
i
s
t
(
s
,
y
)
d
i
s
t
(
s
,
v
)
=
2
∗
d
i
s
t
(
x
,
y
)
+
d
i
s
t
(
s
,
t
)
(3)
\begin{aligned} \because dist(u,v)&>dist(u,t) \\ \therefore dist(u,x)+dist(x,v)&>dist(u,x)+dist(x,y)+dist(y,t) \\ \therefore dist(x,v)&>dist(x,y)+dist(y,t) \\ \therefore dist(x,v)+dist(x,y)+dist(s,y)&>2*dist(x,y)+dist(y,t)+dist(s,y) \\ dist(s,v)&=2*dist(x,y)+dist(s,t) \tag{3} \end{aligned}
∵dist(u,v)∴dist(u,x)+dist(x,v)∴dist(x,v)∴dist(x,v)+dist(x,y)+dist(s,y)dist(s,v)>dist(u,t)>dist(u,x)+dist(x,y)+dist(y,t)>dist(x,y)+dist(y,t)>2∗dist(x,y)+dist(y,t)+dist(s,y)=2∗dist(x,y)+dist(s,t)(3)
∴
d
i
s
t
(
s
,
v
)
>
d
i
s
t
(
s
,
t
)
(4)
\therefore dist(s,v)>dist(s,t) \tag{4}
∴dist(s,v)>dist(s,t)(4)
显然矛盾。
为什么不能处理负权图
事实上,如果以一个严谨的角度去考察上述证明,应该就能发现证明中隐含着的前提。其实这些东西本该在一开始便提出,但当我从各种博客中学习这个算法时,并没有看到相关前提的提出以及对本问题如此详尽的分类证明。本着希望读者能和我一样在面对不严谨的网络资源时能严谨的考量其中知识的目的,我写下这篇博客,并将不能处理负权图的说明放在了常规证明的后面。
首先对于这种情况,如果整棵树的边都为负权,显然 m a x { d i s t ( s , v ) , d i s t ( v , t ) } < 0 max\{dist(s,v),dist(v,t)\}<0 max{dist(s,v),dist(v,t)}<0,那么 m a x { d i s t ( s , v ) , d i s t ( v , t ) } + d i s t ( u , v ) > d i s t ( u , v ) max\{dist(s,v),dist(v,t)\}+dist(u,v)>dist(u,v) max{dist(s,v),dist(v,t)}+dist(u,v)>dist(u,v)的变形会使不等式左边变小,不一定成立。
其次对于这种情况,如果 d i s t ( x , y ) < 0 dist(x,y)<0 dist(x,y)<0,则 ( 3 ) (3) (3)到 ( 4 ) (4) (4)的推理过程并不成立。

本文分析了使用DFS/BFS求解树的直径的正确性,通过反证法证明距任意点最远的点是直径端点之一。同时探讨了为何这种方法无法应用于负权图,指出负权可能导致不等式失效,从而影响算法的准确性。
352

被折叠的 条评论
为什么被折叠?



