zoukankan      html  css  js  c++  java
  • hihoCoder 1050 树中的最长路 最详细的解题报告

    题目来源:树中的最长路

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

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

      1 import java.util.*;
      2 
      3 public class Main {
      4 
      5     public class Node {
      6         public Node parent;//父节点
      7         public List<Node> children;//子节点
      8         public int first;  //最长路
      9         public int second;//次长路
     10         public int val;
     11 
     12         public Node(int val, Node parent) {
     13             this.val = val;
     14             this.first = 0;
     15             this.second = 0;
     16             this.parent = parent;
     17             this.children = new ArrayList<Node>();
     18         }
     19 
     20         //更新节点的first和second
     21         public void update() {
     22             if (this.children.size() == 0) {//叶节点
     23                 this.first = this.second = 0;
     24             } else if (this.children.size() == 1) {//只有一个子节点
     25                 this.first = this.children.get(0).first + 1;
     26                 this.second = 0;
     27             } else {//大于等于2个子节点
     28                 int[] array = new int[this.children.size()];
     29                 for (int i = 0; i < this.children.size(); i++) {
     30                     array[i] = this.children.get(i).first;
     31                 }
     32                 Arrays.sort(array);
     33                 this.first = array[array.length - 1] + 1;
     34                 this.second = array[array.length - 2] + 1;
     35             }
     36         }
     37 
     38         //更新所有节点的first和second(在第一次建立树时调用)
     39         public void updateAll() {
     40             for (Node child : this.children) {
     41                 child.updateAll();
     42             }
     43             this.update();
     44         }
     45     }
     46 
     47     public int n;
     48     public int index;
     49     public int max;
     50     public Node[] nodeMap;
     51 
     52     public Main(Scanner scanner, int n) {
     53         this.n = n;
     54         this.nodeMap = new Node[this.n + 1];
     55         for (int i = 0; i < n - 1; i++) {
     56             this.create(scanner.nextInt(), scanner.nextInt());
     57         }
     58         this.index = 1;
     59         this.nodeMap[this.index].updateAll();//更新所有的节点
     60         this.max = this.nodeMap[this.index].first
     61                 + this.nodeMap[this.index].second;
     62         this.index++;
     63     }
     64 
     65     //创建树
     66     private void create(int from, int to) {
     67         Node parent = this.nodeMap[from];
     68         Node child = this.nodeMap[to];
     69         if (parent == null) {
     70             parent = new Node(from, null);
     71             this.nodeMap[from] = parent;
     72         }
     73         if (child == null) {
     74             child = new Node(to, parent);
     75             this.nodeMap[to] = child;
     76         }
     77         child.parent = parent;
     78         parent.children.add(child);
     79     }
     80 
     81     //将下标为i的节点设置为根节点
     82     private void setRoot(int i) {
     83         Node cur = this.nodeMap[i];
     84         Node parent = cur.parent;
     85         if (parent != null) {//如果存在父节点
     86             parent.children.remove(cur);//从父节点中删除子节点
     87             this.setRoot(parent.val);//递归计算父节点
     88             cur.children.add(parent);//将父节点变成子节点
     89             parent.parent = cur;
     90         }
     91         cur.update();//更新当前节点
     92     }
     93 
     94     public void solve() {
     95         while (this.index <= this.n) {
     96             this.setRoot(this.index);
     97             this.nodeMap[this.index].parent = null;//根节点的parent设置为null,否则出现死循环
     98             int sum = this.nodeMap[this.index].first
     99                     + this.nodeMap[this.index].second;
    100             this.index++;
    101             this.max = this.max > sum ? this.max : sum;//更新max
    102         }
    103     }
    104 
    105     public static void main(String[] args) {
    106         Scanner scanner = new Scanner(System.in);
    107         int N = scanner.nextInt();
    108         Main main = new Main(scanner, N);
    109         main.solve();
    110         System.out.println(main.max);
    111     }
    112 
    113 }
  • 相关阅读:
    HITCON Training lab14 magic heap 堆技巧unsroted bin attack
    堆技巧Unsorted Bin Attack
    2014-hack-lu-oreo 堆技巧house of spirit
    极客时间JVM虚拟机
    堆技巧 housr_of_spirit 绕过检查源码分析
    babyheap_0ctf_2017 堆技巧 fastbin-attack
    gyctf_2020_borrowstack wp
    SqlServer Where后面Case When语句的写法
    EasyUI TextBox的onkeypress事件
    SQL
  • 原文地址:https://www.cnblogs.com/pinxiong/p/4084075.html
Copyright © 2011-2022 走看看