树的直径

可以通过两次\(dfs\)\(bfs\)求出树的直径,从任意结点出发,搜索得出直径的一个端点,然后从这个端点继续搜索,得出另一个端点,但无法处理负边权

\(code\):

void dfs_find(int x,int fa,int de)
{ 
	if(de>=maxd)
	{
		maxd=de;//更新长度
		nd=x;//更新端点
	}
	for(int i=head[x];i;i=e[i].nxt)
	{
		int y=e[i].to,v=e[i].v;
		if(y==fa) continue;
		dfs_find(y,x,de+v);
	}
}

也可以用树形\(DP\)求直径,考虑每个结点\(x\),求出经过结点\(x\)的最长链长度,则树的直径长度就是这些最长链长度的最大值,但无法求出直径的端点

\(code\):

void dp(int x,int fa)
{
    for(int i=head[x];i;i=e[i].nxt)
	{
        int y=e[i].to,v=e[i].v;
		if(y==fa) continue;
        dp(y,x);
        maxd=max(maxd,dis[x]+dis[y]+v);
        dis[x]=max(dis[x],dis[y]+v);
    }
}

巡逻,两种方法结合,巧妙运用直径

posted @ 2020-01-22 20:09  lhm_liu  阅读(132)  评论(0编辑  收藏  举报