C C++ 题解LeetCode2360图中的最长环示例

让我们详细讲解一下“C C++ 题解LeetCode2360图中的最长环示例”的完整攻略。

题目描述

题目传送门:LeetCode2360图中的最长环

题目描述:

给你一棵有n个节点的有根树,节点从0~n-1编号,树的根节点为0.

叶节点是指没有直接连接任何下一级节点的节点。本题中,树的节点从1到n编号, 而非从0到n-1编号.

节点 i 的父亲是 father[i]。一个节点的直接子节点是该节点连接的所有节点中编号最小的那些。例如,在图中的树中,节点 1 连接着节点 2 和节点 3 且节点 2 是节点 1 的子节点,节点 3 是节点 1 的另一个直接子节点。该树经过修改变成了一棵普通的无根树。你需要重新连接树边,以得到一棵直径最大的树。直径是树上最长路径的长度。用所需修改的边的个数来返回该长度。

题目分析

在题目中,我们需要把一个有根树转化为无根树,然后求出该无根树的直径,再根据需要修改的边数返回最长的直径长度。

先看怎样将一个有根树转化为无根树。我们可以让树中的任意一个节点作为根节点,以其他节点为根节点建立子树。但是,本题中我们并不知道那个节点才是原来的根节点。因此,我们需要枚举所有的节点作为根节点,以该节点为根节点建立子树并求出该子树的最长直径。最终所有的直径长度中的最大值即为所求。

无根树的直径可以用两次dfs求出,详细的求解过程可以参见我的博客:无根树的直径

接下来,我们再看怎样计算其中添加的边数。

我们发现,在有根树中,父节点到子节点的边是确定的。因此,每当我们枚举一个节点作为根节点并对树进行转化时,会造成一部分父节点到子节点的边的改变,不同姿势转换成的无根树造成的改变不同,我们需要对这些结果进行分析。

我们采用dfs从一个虚拟的根节点 root 开始遍历整个无根树,记录每个节点到虚拟根节点的距离,并维护一条最长路径,路径上的两个节点即为无根树的直径的两个端点。如果某个节点的两个子节点的距离和大于现有的最长路径长度,则更新最长路径。记录这个最长路径长度 later。

要想得出我们需要添加的边数 diff,先计算出无根树之前的最长直径长度 former。

diff = later - former。

最后,我们就可以得到这道题的完整解法了。

一条示例说明

以示例图为例,具体思路如下:

  1. 先将节点0作为根节点, 枚举所有节点, 以该节点为根建立无根树, 并计算该无根树的直径, 该部分的添加的边数为3.
  2. 然后将节点1作为根节点, 输入的树在以节点1为根的树形结构中的样子为:
   1(1)
  /     \
2(2)    3(4)

计算该树的时候需要修改2到4的路径,因此 diff = 1。最长直径为2。因此我们最重终态的答案应该为5 + 2 = 7

  1. 最后再枚举2和3各一次即可。

不难发现,我们需要维护两个比较重要的变量:later 和 former。 下一个示例同理。

另一条示例说明

现在看练习题目传送门:第 113 周周赛 第二题

给出的树形结构为:

   3(1)
  /     \
2(2)    0(3)
   \     
    1(4)

初始无根树:

   3(1)
  /     \
2(2)    0(3)
   \     
    1(4)

以 3 作为根:

   3(1)
  /     \
2(2)    0(3)
   \     
    1(4)

该部分的添加边数为1,最长路径为1。

以 2 作为根:

       2(1)
      /   \
    3(2)  1(4)
      \     
       0(3)

该部分的添加边数为1,最长路径为3。

以 0 作为根:

   0(1)
  /     \
3(2)    2(3)
   \     
    1(4)

该部分的添加边数为1,最长路径为3。

以上两例都说明了这个题的思路,对于这些奇怪的示例可以用调试模式查看获得更好的体验。

代码实现

参考代码如下:

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C C++ 题解LeetCode2360图中的最长环示例 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++智能指针之shared_ptr详解

    C++智能指针之shared_ptr详解 什么是智能指针 智能指针是一种特殊类型的指针,它会自动管理指针所指向的内存,从而避免了因为内存管理不当而导致的内存泄露、多次释放等问题。C++11中提供了三种智能指针:unique_ptr、shared_ptr和weak_ptr。 shared_ptr的介绍 shared_ptr是一种智能指针,它可用于多个指针共享同…

    C 2023年5月23日
    00
  • C语言实现实验设备管理系统

    C语言实现实验设备管理系统 简介 C语言是一种面向过程的编程语言,广泛应用于系统软件、存储管理、操作系统、网络协议等领域。实验设备管理系统是一种重要的实验室管理工具,在实验室管理中得到广泛应用。本文将详细讲解如何使用C语言实现实验设备管理系统。 环境配置 在开始编写代码之前,需要先配置好C语言的开发环境。以下是环境配置的基本步骤: 安装C语言编译器,建议选择…

    C 2023年5月23日
    00
  • 数据转换冲突及转换过程中大对象的处理

    数据转换冲突及转换过程中大对象的处理 在进行数据转换时,可能会出现数据类型不匹配或者数据格式不兼容等问题,这会导致数据转换失败。同时,数据转换过程中可能会涉及到大对象(如图片、视频等),如何处理这些大对象也是值得关注的问题。 在处理数据转换中的冲突问题时,我们需要注意以下几点: 确定数据类型 在进行数据转换之前,首先需要明确源数据和目标数据的类型。如果类型不…

    C 2023年5月22日
    00
  • JS的深浅复制详细

    下面是JS的深浅复制详细攻略。 什么是JS的深浅复制 在JS中,复制一个对象分为浅复制和深复制两种。所谓浅复制就是对象的最外层属性复制到新的对象中,而内层对象以及数组等引用类型则只是将引用地址复制了一份。而深复制则是将对象及其所有嵌套对象、数组等整个复制一份。 浅复制示例 在JS中,可以使用Object.assign()函数来实现浅复制。 let obj1 …

    C 2023年5月23日
    00
  • C++实现简单班级成绩管理系统

    C++实现简单班级成绩管理系统攻略 1. 需求分析 在实现班级成绩管理系统前,首先需要明确实现系统的主要功能,如本系统需要实现的功能有:- 添加学生的基本信息,包括学生姓名和学号;- 添加学生成绩信息,包括数学、语文、英语等科目的成绩;- 对学生成绩进行管理,包括查看某个学生的成绩、某个科目的平均成绩、班级总体平均成绩等。 2. 设计思路 本系统的设计思路为…

    C 2023年5月30日
    00
  • 2048小游戏C语言实现代码

    首先,2048小游戏是一款经典的益智游戏,玩家需要通过合并数字达到2048的目标。对于C语言实现,代码可以分为几个部分:界面显示、随机数字生成、输入处理、数字移动和合并、判断游戏是否结束。 界面显示 为了在终端中显示2048的游戏界面,我们需要使用C语言的库函数ncurses。首先,需要安装ncurses库,在Ubuntu系统下使用以下命令安装: sudo …

    C 2023年5月24日
    00
  • C语言小程序 如何判断三角型类型

    要判断一个三角形的类型,需要先知道这个三角形的三边长度。以下是完整攻略: 首先,需要从用户处获取三角形的三条边长,可以采用以下代码读取用户输入的三边: double a, b, c; scanf("%lf%lf%lf", &a, &b, &c); 接下来,需要判断输入的边长是否可以组成三角形。可以用以下代码来实现:…

    C 2023年5月23日
    00
  • 非常好的12道shell命令经典面试问题

    整个攻略分为以下几个部分: 介绍12个经典的面试问题 每个问题的解答及解析 给出示例说明 1. 介绍12个经典的面试问题 以下是12个经典的面试问题: 如何显示当前的工作目录? 如何检查一个命令是否在系统中存在? 如何列出目录中所有文件的名称? 如何列出一个文件的前10行? 如何查找文件中的特定文本? 如何在Linux上安装软件包? 如何查看一个文件的大小?…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部