给定一颗树 T = ( V , E ) T=\left(V,E\right) T=(V,E) 直径为 m a x l e n ( u , v ) ( u , v ∈ V ) maxlen(u,v)(u,v\in V) maxlen(u,v)(u,v∈V)
树的直径普遍有两种求法,一个是两边 b f s / d f s bfs/dfs bfs/dfs另一个就是树形DP
这颗树的直径很明显,就是 ( 8 , 14 ) (8,14) (8,14)
而如何用代码实现呢?
首先令:
f i , 1 f_{i,1} fi,1为点 i i i能到达的最远的距离
f i , 2 f_{i,2} fi,2为点 i i i能到达的次远的距离
则
f i , 1 = max j ∈ i f j , 1 + l e n ( i , j ) f_{i,1}=\max_{j\in i}^{}{f_{j,1}+len(i,j)} fi,1=j∈imaxfj,1+len(i,j)
f i , 2 = max k ∈ i & & k ≠ j f k , 1 + l e n ( i , k ) f_{i,2}=\max_{k\in i\ \&\&\ k\not=j }^{}{f_{k,1}+len(i,k)} fi,2=k∈i && k=jmaxfk,1+len(i,k)
m a x l e n = max i ∈ V ( m a x l e n , f i , 1 + f i , 2 ) maxlen=\max_{i\in V}(maxlen,f_{i,1}+f_{i,2}) maxlen=i∈Vmax(maxlen,fi,1+fi,2)
这样便实现了一遍遍历找出树的直径
找到一个点,其所有的子树中最大的子树节点数最少
令:
N N N为所有节点数
f i f_i fi为 i i i的子树的个数
m i m_i mi为 i i i的子树的节点数的最大值
则:
m i = max j ∈ i f j m_i=\max_{j\in i}{f_j} mi=j∈imaxfj
f i = ∑ j ∈ i f j f_i=\sum_{j\in i}{f_j} fi=j∈i∑fj
a n s = min i ∈ V ( a n s , max ( m i , N − f i ) ) ans=\min_{i\in V}(ans,\max(m_i,N-f_i)) ans=i∈Vmin(ans,max(mi,N−fi))