• 树上问题——树的直径


    树的直径的含义

    树的直径就是树中所有最短路经距离的最大值。

    求树的直径通常有两种方法,一种是通过两次搜索(bfs和dfs均可),另一种就是通过树形dp来求了。

    dfs(bfs)求树的直径

    随便从一个点 a a a开始,用dfs找到离初始点最远的点 b b b。然后再以最远点 b b b为初始点用dfs找到离初始点最远的点 c c c

    路径 b c bc bc即为当前树的直径。

    int e,maxv=-1;
    void dfs(int x,int father)
    {
    	for(int i=h[x];i!=-1;i=ne[i])//用链式前向星存树
    	{
    		int j=e[i];
    		if(j==father) continue;//树是一种有向无环图,只要搜索过程中不返回父亲节点即可保证不会重复遍历同一个点。
    		d[j]=d[x]+w[i];//更新每个点到起始点的距离(在树中任意两点的距离是唯一的)
            if(d[j]>maxv) maxv=d[j],e=j;//更新最远的点的信息
    		dfs(j,x);//继续搜索下一个节点
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    树形dp求树的直径

    首先递归到叶结点,然后再由叶结点连接父节点,更新 f 1 , f 2 f1,f2 f1,f2数组( f 1 [ i ] f1[i] f1[i]数组表示离点i最远的点的距离, f 2 [ i ] f2[i] f2[i]数组表示离点i次远的点的距离)。

    最后找到任意一点的 f 1 + f 2 f1+f2 f1+f2最大的值,该值即为树的直径。

    void dp(int x,int father)
    {
    	for(int i=h[x];i!=-1;i=ne[i])链式前向星存树
    	{
    		int j=e[i];
    		if(j==father) continue;//防止原路返回
    		dp(j,x);//dp过程应该是由叶节点开始的,也就是说先递归到叶节点再开始进行状态转移
    		if(f1[x]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    3、IOC——基于注解管理bean
    Java - 根据文件绝对路径,来删除文件
    统计学习方法 感知机
    安装RocketMq流程及踩坑
    数字经济崛起,企业数字化转型的底层逻辑
    google浏览器安装vuejs-devtools插件2022年安装记录
    简简单单一段话描述设计模式
    自然语言处理学习笔记(十一)————简繁转换与拼音转换
    【性能监控】如何有效监测网页静态资源大小?
    torch的gpu上做fft,其中dim参数含义解释
  • 原文地址:https://blog.csdn.net/qq_57109165/article/details/126708979