【学习笔记】树的重心

树的重心:对于一颗n个结点的无根树,找到一个点,使得把树变成以该点为跟的有根树时,最大子树的结点数最小,就是说如果删除这个点后,所形成的森林中,最大的树的结点数最小。

性质:

<1>树中所有结点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离和,则他们的距离和一样。

<2>把两棵树通过一条边相连,新的树的重心在原来两棵树重心的连线上。

<3>一棵树添加或者删除一个结点,树的重心最多只移动一条边的位置。

<4>一棵树最多有两个重心且相邻。

dfs求树的重心:(POJ3107板子题,但是这个代码会T,换成前向星才能过)

d[i]表示:以i为根的子树的结点个数,在dfs的过程中就可以求出,所以根据树的重心的定义就可以比较清楚地写出来这个代码。siz代表的就是总答案,res代表以now为根节点的局部答案,我们每回需要计算的res=max{d[son],n-d[now]},即我的每个子树的结点个数和除我这棵树以外的结点当子树的结点个数的最大值。回溯的时候一步步上来就行了。

#include 
#include 
#include 
using namespace std;
const int maxn=50005;
const int inf=0x7fffffff;
vector e[maxn];
int n;
int d[maxn];
int siz;
vector id;
void dfs(int now,int pre)
{
	d[now]=1;
	int res=0;
	int sz=e[now].size();
	for(int i=0;i>n;
	for(int i=1;i>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	siz=inf;id.clear();
	dfs(1,-1);
	sort(id.begin(),id.end());
	for(int i=0;i

你可能感兴趣的:(个人学习感悟)