树的直径
树的直径
树的直径即是树中相距最远的两个点的距离。相距最远指的是两点间的最短路径的距离最远。
算直径有两种方法
DFS
- 任取起点,先做一次DFS,找到距离最远的点,这个点一定是直径的一部分。
- 从这个点开始再做一次DFS,找到离它最远的点,这两个点就组成了直径
树上DP
假设f1[x],f2[x]分别是x到其子树的叶子节点距离的最大值和次大值。j是i的直接后继,则有:
- 如果f1[i] < f1[j] + w[i, j]则f2 [ i ] = f1 [ i ],f1 [ i ] = f1 [ j ] + w [ i ][ j ]
- 否则,若 f2 [ i ] < f1 [ j ] + w [ i ][ j ],则f2 [ i ] = f1 [ j ] + w [ i ][ j ];
最后,直径就是
核心代码
void dp(int x,int father)
{
int i,j;
for(i=first[x];i;i=next[i])
{
j=v[i];
if(j==father)
continue;
dp(j,x);
if(f1[x]<f1[j]+w[i])
{
f2[x]=f1[x];
f1[x]=f1[j]+w[i];
}
else if(f2[x]<f1[j]+w[i])
f2[x]=f1[j]+w[i];
ans=max(ans,f1[x]+f2[x]);
}
}