淺談關於樹形dp求樹的直徑問題


在一個有n個節點,n-1條無向邊的無向圖中,求圖中最遠兩個節點的距離,那么將這個圖看做一棵無根樹,要求的即是樹的直徑。####

求樹的直徑主要有兩種方法:樹形dp和兩次bfs/dfs,因為我太菜了不會寫后者這里只介紹樹形dp

  • 樹形dp求樹的直徑
    我們不妨設1號點為根節點,那么這就可以看做一棵有根樹。
    設D[x]表示從節點x出發,往以x為根的子樹走,能夠到達的最遠距離。設x的子節點分別為\(y_1,y_2,y_3,...,y_t\)\(edge(x,y)\)表示從x到y的邊權,則可以得到狀態轉移方程:
    \(D[x]={(D[y_i]+edge(x,y_i))}_{max}\)
    接下來,我們考慮對於每個節點x求出經過x的最長鏈的長度F[x],整棵樹的直徑就是max{F[x]}(1<=x<=n)。

    現在我們考慮如何求F[x]。
    對於任意兩個節點yi和yj,經過節點x的最長鏈的長度可以通過四個部分來構成:

    • D[yi]
    • D[yj]
    • 從x到yi的距離
    • 從x到yj的距離

    不妨設j<i,則有:

\(F[x]= {(D[y_i]+D[y_j]+edge(x,y_i)+edge(x,y_j))}_{max}\)

對應代碼如下:

void dp(int x){
	v[x]=1;	
	for(register int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(v[y])continue;	
		dp(y); 
		ans=max(ans,d[x]+d[y]+edge[i]);
		d[x]=max(d[x],d[y]+edge[i]);
	}
}

代碼解釋可以看圖:

參考資料:李煜東《算法競賽進階指南》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM