树的直径
定义
树的直径指树上距离最远的两点间的距离。
性质
① 直径两端点一定是两个叶子节点。
② 距离任意点最远的点一定是直径的一个端点,这个基于贪心求直径方法的正确性可以得出。
③ 对于两棵树,如果第一棵树直径两端点为(u,v),第二棵树直径两端点为(x,y),用一条边将两棵树连接,那么新树的直径一定是u,v,x,y,中的两个点。
④ 对于一棵树,如果在一个点的上接一个叶子节点,那么最多会改变直径的一个端点。
⑤ 若一棵树存在多条直径,那么这些直径交于一点且交点是这些直径的中点。
求解
DP
令dp[s]为s子树方向的最大距离,ans为直径。
void DP(int s,int fa)
{
int i,v;
for(i=head[s];i!=-1;i=e[i].next)
{
v=e[i].v;
if(v==fa) continue;
DP(v,s);
ans=max(ans,dp[s]+dp[v]+e[i].w);
dp[s]=max(dp[s],dp[v]+e[i].w);
}
}
DFS|BFS
任意找一点为根,进行BFS|DFS找到最远点A,以A为根,进行BFS|DFS找到最远点B,AB则为直径。
①DFS(1,-1,0); ②DFS(A,-1,0); pos表示最远点。
void DFS(int s,int fa,int deep)
{
int i,v;
if(mmax<deep) mmax=deep,pos=s;
for(i=head[s];i!=-1;i=e[i].next)
{
v=e[i].v;
if(v==fa) continue;
DFS(v,s,deep+1);
}
}