樹的直徑指樹上距離最遠的兩點間的距離,它在樹上問題上有許多應用,每每經過樹的直徑的性質能夠將一個高時間複雜度的解法變爲線性求解。對於樹上兩點間距離一般有三種定義,咱們根據這三種狀況分別討論一下它的性質。spa
樹的直徑有兩種求法,時間複雜度都是$O(n)$。方法
貪心求直徑的方法是任意找一個點爲根,dfs整棵樹找到距離他最遠的點$x$,再以這個點$x$爲根求出距離它最遠的點$y$,$(x,y)$即爲直徑。證實後面再說。di
DP求直徑的方法是對於每一個點記錄這個點子樹中的最長鏈及與最長鏈處於不一樣子樹中的次長鏈,用每一個點的最長鏈+次長鏈更新直徑,而後再將最長鏈上傳到父節點更新父節點的最長鏈或次長鏈。這種求法適用於全部求樹的直徑的狀況。時間
定義兩點間距離爲兩點間路徑上的邊權和,邊權非負。上傳
貪心求直徑的方法適用於這種樹的直徑。
假設肯定了直徑的一個端點,那麼另外一個端點必定是距離這個端點最遠的點,因此第二次找最遠點的貪心必定正確。咱們採用反證法,假設第一次從$a$開始找,找到的點是$x$,而存在一個點$u$使得以$u$爲根找最遠點$v$造成的直徑要比以$x$爲根找最遠點造成的直徑長。假設兩點間距離用$dis$表示
若是$(x,u)$的路徑與$(u,v)$的路徑不相交,$dis(x,u)+dis(u,v)$必定比$dis(u,v)$長,假設不成立。
若是$(x,u)$的路徑與$(u,v)$的路徑相交,假設兩路徑的另外一交點爲$y$,那麼$dis(x,y)>dis(u,y)$,由於以$a$爲根時$x$的深度比$u$的深度深,因此手畫一下就能看出來。
一、直徑兩端點必定是兩個葉子節點
二、距離任意點最遠的點必定是直徑的一個端點,這個基於貪心求直徑方法的正確性能夠得出
三、對於兩棵樹,若是第一棵樹直徑兩端點爲$(u,v)$,第二棵樹直徑兩端點爲$(x,y)$,用一條邊將兩棵樹鏈接,那麼新樹的直徑必定是$u,v,x,y,$中的兩個點
四、對於一棵樹,若是在一個點的上接一個葉子節點,那麼最多會改變直徑的一個端點
五、若一棵樹存在多條直徑,那麼這些直徑交於一點且交點是這些直徑的中點
定義樹的直徑爲兩點間路徑上邊權和+兩點點權和,點權能夠爲負數,邊權非負。
這種狀況知足貪心求法及上述二、3性質,一樣證實一下貪心求法及性質2:
能夠發現性質二知足的緣由是貪心求法的成立,因此只須要證實貪心的成當即可。
假設第一次dfs以$a$爲根,深度+點權的最大點爲$x$,假設存在一個更優勢$u$使得從$u$開始找最遠點$y$造成的直徑比從$x$找最遠點造成的直徑長,令$x$與$u$到根的路徑不交集部分長度分別爲$l(x),l(u)$,兩點點權分別爲$v(x),v(u)$,那麼$l(x)+v(x)>l(u)+v(u)$。
若是$(u,y)$與$(x,u)$不相交,那麼顯然$v(x)+l(x)+l(u)>v(u)$,$dis(x,u)+dis(u,y)+v(x)+v(y)>dis(u,y)+v(u)+v(y)$
若是$(u,y)$與$(x,u)$相交,假設兩路徑交點爲$b$,那麼也能夠得出$dis(b,x)+v(x)>dis(b,u)+v(u)$的結論
定義樹的直徑爲兩點間路徑上邊權和,邊權有負數。
這種狀況沒法用貪心方法求直徑,而且不具有以上性質。