题目来源:树中的最长路

解题思路:枚举每一个点作为转折点t,求出以t为根节点的子树中的‘最长路’以及与‘最长路’不重合的‘次长路’,用这两条路的长度之和去更新答案,最终的答案就是这棵树的最长路长度。只要以类似后序遍历的方式依次访问每个结点,从下往上依次计算每个结点的first值和second值,就能够用O(N)的时间复杂度来解决这个问题。

具体算法(java版,可以直接AC)

 import java.util.*;

 public class Main {

     public class Node {
public Node parent;//父节点
public List<Node> children;//子节点
public int first; //最长路
public int second;//次长路
public int val; public Node(int val, Node parent) {
this.val = val;
this.first = 0;
this.second = 0;
this.parent = parent;
this.children = new ArrayList<Node>();
} //更新节点的first和second
public void update() {
if (this.children.size() == 0) {//叶节点
this.first = this.second = 0;
} else if (this.children.size() == 1) {//只有一个子节点
this.first = this.children.get(0).first + 1;
this.second = 0;
} else {//大于等于2个子节点
int[] array = new int[this.children.size()];
for (int i = 0; i < this.children.size(); i++) {
array[i] = this.children.get(i).first;
}
Arrays.sort(array);
this.first = array[array.length - 1] + 1;
this.second = array[array.length - 2] + 1;
}
} //更新所有节点的first和second(在第一次建立树时调用)
public void updateAll() {
for (Node child : this.children) {
child.updateAll();
}
this.update();
}
} public int n;
public int index;
public int max;
public Node[] nodeMap; public Main(Scanner scanner, int n) {
this.n = n;
this.nodeMap = new Node[this.n + 1];
for (int i = 0; i < n - 1; i++) {
this.create(scanner.nextInt(), scanner.nextInt());
}
this.index = 1;
this.nodeMap[this.index].updateAll();//更新所有的节点
this.max = this.nodeMap[this.index].first
+ this.nodeMap[this.index].second;
this.index++;
} //创建树
private void create(int from, int to) {
Node parent = this.nodeMap[from];
Node child = this.nodeMap[to];
if (parent == null) {
parent = new Node(from, null);
this.nodeMap[from] = parent;
}
if (child == null) {
child = new Node(to, parent);
this.nodeMap[to] = child;
}
child.parent = parent;
parent.children.add(child);
} //将下标为i的节点设置为根节点
private void setRoot(int i) {
Node cur = this.nodeMap[i];
Node parent = cur.parent;
if (parent != null) {//如果存在父节点
parent.children.remove(cur);//从父节点中删除子节点
this.setRoot(parent.val);//递归计算父节点
cur.children.add(parent);//将父节点变成子节点
parent.parent = cur;
}
cur.update();//更新当前节点
} public void solve() {
while (this.index <= this.n) {
this.setRoot(this.index);
this.nodeMap[this.index].parent = null;//根节点的parent设置为null,否则出现死循环
int sum = this.nodeMap[this.index].first
+ this.nodeMap[this.index].second;
this.index++;
this.max = this.max > sum ? this.max : sum;//更新max
}
} public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
Main main = new Main(scanner, N);
main.solve();
System.out.println(main.max);
} }

hihoCoder 1050 树中的最长路 最详细的解题报告的更多相关文章

  1. hihocoder 1050 树中的最长路(动态规划,dfs搜索)

    hihocoder 1050 树中的最长路(动态规划,dfs搜索) Description 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅 ...

  2. hihocoder#1050 : 树中的最长路(树中最长路算法 两次BFS找根节点求最长+BFS标记路径长度+bfs不容易超时,用dfs做TLE了)

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  3. 题解报告:hihoCoder #1050 : 树中的最长路

    描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已. 但 ...

  4. hihoCoder #1050 : 树中的最长路

    题意: 求出树上最长路径的长度,并返回. 思路: 刚看到数据<=10^5,假如是单分支的树,那么有5万层,就不能递归,那就用桟实现, 那就要将长度信息保存在另开的数组中,很麻烦!!这题专门给递归 ...

  5. hiho #1050 : 树中的最长路 树的直径

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  6. [HIHO] 1050 树中的最长路

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  7. hihoCoder week11 树中的最长路

    题目链接: https://hihocoder.com/contest/hiho11/problem/1 求树中节点对 距离最远的长度 #include <bits/stdc++.h> u ...

  8. HihoCoder第十一周:树中的最长路

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  9. hihoCoder#1050(树中最长路)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一 ...

随机推荐

  1. MSCHART控件中长字符的X轴坐标标注全部显示

    X轴坐标如果超过9位的话,就不能完全显示了,就会一个隔一个的显示,解决的办法: Chart1.ChartAreas[].AxisX.Interval = ; //设置X轴坐标的间隔为1 Chart1. ...

  2. PyCharm罢工并向你丢出了pip升级需求

    一.事件缘由 最近在搞接口自动化框架,基于python自然少不了使用PyCharm.本来都是 在解决脚本上遇到的坑,突然出现了第三方库安装失败,这感觉就像大热天吃到 冰激凌,昏沉的脑袋瞬间清醒许多. ...

  3. 12.实战交付一套dubbo微服务到k8s集群(5)之交付dubbo-monitor到K8S集群

    dubbo-monitor官方源码地址:https://github.com/Jeromefromcn/dubbo-monitor 1.下载dubbo-monitor源码并解压 [root@hdss7 ...

  4. Latex文件本机能正常编译,但在另一台电脑不能编译的解决方法

    问题:同样的文件在台式机能编译出正常的PDF文件,但发现在另一个电脑上不能编译出PDF文件. \documentclass[preprint,10pt,5p,times,twocolumn]{elsa ...

  5. 一起玩转微服务(10)——spring boot介绍

    对于Spring,相信大家都非常熟悉,从出现开始,一直是企业级开发的主流.但是随着软件的发展和应用开发的不断演化,它的一些缺点也逐渐胡暴露了出来,下面,我们就一起看一下Spring的发展历程并且认识一 ...

  6. JavaWeb网上图书商城完整项目--day02-2.regist页面输入框得到焦点隐藏label

    实现当光标输入在输入输入框的时候,将后面的内容隐藏,例如在用户名称输入信息的时候,后面的用户名不能为空隐藏 我们来看看regist.js的代码: //该函数在html文档加载完成之后会调用 $(fun ...

  7. java scoket Blocking 阻塞IO socket通信三

    在NIO同步非阻塞的场景中和原来同步阻塞最大的却别就是引入了上面的Buffer对象,现在我们来学校上面的BUffer对象 我们来看看程序的代码: package bhz.nio.test; impor ...

  8. MySQL按指定字符合并及拆分

    按照指定字符进行合并或拆分是经常碰到的场景,MySQL在合并的写法上比较简单,但是按指定字符拆分相对比较麻烦一点(也就是要多写一些字符).本文将举例演示如何进行按照指定字符合并及拆分. 1. 合并 M ...

  9. MongoDB快速入门教程(3.1)

    3.MongoDB进阶 3.1.权限验证 以下内容适用于Mac系统用户,window系统用户请看后面文档 3.1.1.创建超级管理员用户 默认情况下连接mongodb是不需要用户名和密码的,这样不安全 ...

  10. HDU3686 Traffic Real Time Query【缩点+lca】

    题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...