首页 > 代码库 > hihoCoder 1050 树中的最长路

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;//更新max102         }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 }

 

hihoCoder 1050 树中的最长路