树的直径

定义

树的直径指树上距离最远的两点间的距离。

性质

①  直径两端点一定是两个叶子节点。
②  距离任意点最远的点一定是直径的一个端点,这个基于贪心求直径方法的正确性可以得出。
③  对于两棵树,如果第一棵树直径两端点为(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);
  }
}
本博客仅为本人学习,总结,归纳,交流所用,若文章中存在错误或有不当之处,十分抱歉,劳烦指出,不胜感激!!!
原文地址:https://www.cnblogs.com/VividBinGo/p/11345187.html