树的直径
- 求法 :两遍dfs分别求出最远的点,所得的两个点为直径的两个端点;
void dfs(int x,int fa)//find d point;
{
int i = last[x];
while(i)
{
int y=en[i];
if(y==fa)
{
i=nex[i]; continue;
}
dfs(y,x);
if(len[i]+gf[y]>gf[x])
{
gf[x]=len[i]+gf[y];
df[x]=df[y];
}
i=nex[i];
}
// printf("---%d %d %lld\n",x,df[x],gf[x]);
if(!df[x])
{
df[x]=x;
gf[x]=0;
return;
}
}
dfs(1,0);
int ed = df[1];
memset(df,0,sizeof df);
memset(gf,0,sizeof gf);
dfs(ed,0);
直径的一些性质:
- 一棵树最多只有两条直径,若有一定有交点,并且交于中点。
- 每个节点的距离最远的点一定是直径的其中一个端点
树的重心
- 含义:树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。