树的直径
通俗的讲就是求树上的最长链的长度
一般有两种求法,各有优势
DP法
用
表示从结点u出发能走到的最远距离
设
为u的子节点
那么有
对于经过结点u的最长链长度
有
那么整个树的最长链就是
整个算法只需一次dfs,时间复杂度
void DP(int u,int pa)
{
dp[u]=0;
for(int i=head[u];i;i=E[i].nxt)
{
int v=E[i].v;
if(v==pa) continue;
DP(v,u);
mxlen=max(mxlen,dp[u]+dp[v]+E[i].dis);
dp[u]=max(dp[u],dp[v]+E[i].dis);
}
}
DFS || BFS 法
算法总共两次dfs或bfs
第一步
从任意节点出发,通过dfs或bfs遍历找到与出发点最远的结点,记为p
第二步
从p出发,通过dfs或bfs遍历找到离p最远的结点,记为q
此时p到q的路径就是树的直径
该算法整体复杂度为
但是可以同时得知直径的具体结点,以便于其他操作
void dfs(int u,int pa)
{
//dp[u]记录从u出发能到达的最远距离,rem[u]记录离u最远的结点
rem[u]=u; dp[u]=0;
for(int i=head[u];i;i=E[i].nxt)
{
int v=E[i].v;
if(v==pa) continue;
dfs(v,u);
if(dp[u]<=dp[v]+E[i].dis)
dp[u]=dp[v]+E[i].dis,rem[u]=rem[v];
}
}
dfs1(1,0); p=rem[1];
dfs1(p,0); q=rem[p];
需要特别注意的是