求树的直径算法
求树的直径算法
标签: 图论——树的直径
阅读体验:https://zybuluo.com/Junlier/note/1251025
树的直径
树的直径是树上的最长路
求法:2遍\(Dfs(Bfs)\)
没错,真的这么简单......
- 先随便找个点i开始\(Dfs\),然后找到一条最长路径(假设终点是\(u\))
- 然后从u开始再一次\(Dfs\),再找到一条最长路径(假设终点是\(v\)),\((u,v)\)就是树的直径了......
PS:树的直径可以有多条(想想定义就知道)
证明:为什么呢?
假设树的直径是\((u,v)\),第一次\(Dfs\)找到\((i,j)\)
如果我们\(Dfs\)找到了树的直径的一端\((u/v)\),那么第二次就一定可以找到树的直径对吧
那么证明转化成了第一次\(Dfs\)是否找到了树的直径的一端\((u/v)\)
PS:建议自己手动画棵树来一边看着证明 效果更佳
首先假设i在最长路径上:
- 反证法:
- 如果找到的
(i,j)
不是(i,u)
,那么(i,j)
一定可以和(i,v)
拼成另一条更长路(j,v)
(因为(i,j)>=(i,u)
而等于正印证了上面讲到的多条直径),所以与假设(u,v)
是最长路不符,那么猜想的方法成立
如果i不在最长路上呢?
- 首先\(i\)肯定可以和最长路上的一个点\(k\)(从\(i\)到最长路最先遇到的点)连通对吧
- 我们假设\(u\)是最长路距离\(k\)较远的一个末端,那么从\(i\)找出去的最长路一定会到\(u\)
- 证明:如果
(i,j)
不是(i,u)
(即(i,j)>(i,u)
),那么(i,j)+(i,k)>(j,u)
,即我们找到了另一条(j,k)>(j,u)
,那么说明我们假设的直径(u,v)
又可以被更长的(k,v)
更新,假设不成立,那么猜想成立,证明完毕
总结一下
综上所述,两遍\(Dfs(Bfs)\)可以找到树的直径
而树的直径在很多图论题里面是很有用的,这种方法就保证了我们的时间复杂度O(n)
为我们其他计算提供了更优的复杂度空间。。。
\(yep\)
推荐题目
P2491 [SDOI2011]消防(有难度的啊)(只放了洛谷的地址,各大\(OJ\)应该都有)
哪怕人间是炼狱,梦想永远是天堂
继续走下去吧,理想永远都年轻,花儿一定会再次盛开