關於樹的重心


(由於本人太菜所以最近一直在補一些基礎算法……)

求樹的重心的基本思想就是從每個節點出發分別遍歷一遍樹,統計max_part,其中能夠使得max_part最小的就是樹的重心

另外:一棵有根樹至多有兩個重心,這個結論好像有些題可以用(比如BZOJ4337,不過那個數據太水只有50(什么暴力亂搞都能過去),但據高三的DZYO神仙說數據可以出到1e6)

大部分的解釋都在代碼里面(其實沒有什么好解釋的……我解釋了下各個變量的意思)

/*
樹的重心定義:對於一個樹中節點x,當我們刪去它時會將原來的樹分割成若干個不相連的部分,其中每個部分都是一顆子樹。
設max_part表示這些部分中最大的一棵子樹,若刪去節點x能夠使得max_part最小,則稱這個點為樹的重心 
*/
void Dfs(int x){
	/*
	v[i]:遍歷的時候打標記 
	size[i]:刪去x后以i為根的子樹的大小
	max_part:刪去x之后大小最大的子樹的大小
	pos:搜索到現在使得max_part最小的節點 
	ans:搜到現在max_part的最小值 
	*/ 
	v[x]=1; size[x]=1;
	int max_part=0;
	for(register int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(v[y])continue;
		Dfs(y);
		size[x]+=size[y];
		max_part=max(max_part,size[y]);
	}
	max_part=max(max_part,n-size[x]);
	if(max_part<ans){
		ans=max_part;
		pos=x;
	}
}

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


免責聲明!

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



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