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 }

 

posted @ 2014-11-08 21:49  PinXiong  阅读(766)  评论(0编辑  收藏  举报