package class14; // 本题测试链接 : https://www.nowcoder.com/practice/e13bceaca5b14860b83cbcc4912c5d4a // 请同学们务必参考如下代码中关于输入、输出的处理 // 这是输入输出处理效率很高的写法 // 提交以下所有代码,并把主类名改成Main // 可以直接通过 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class Code03_BiggestBSTTopologyInTree { public static int MAXN = 200001; public static int[][] tree = new int[MAXN][3]; public static int[] record = new int[MAXN]; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StreamTokenizer in = new StreamTokenizer(br); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); while (in.nextToken() != StreamTokenizer.TT_EOF) { int n = (int) in.nval; for (int i = 1; i <= n; i++) { tree[i][0] = 0; tree[i][1] = 0; tree[i][2] = 0; record[i] = 0; } in.nextToken(); int h = (int) in.nval; for (int i = 1; i <= n; i++) { in.nextToken(); int c = (int) in.nval; in.nextToken(); int l = (int) in.nval; in.nextToken(); int r = (int) in.nval; tree[l][0] = c; tree[r][0] = c; tree[c][1] = l; tree[c][2] = r; } out.println(maxBSTTopology(h)); out.flush(); } } // h: 代表当前的头节点 // t: 代表树 t[i][0]是i节点的父节点、t[i][1]是i节点的左孩子、t[i][2]是i节点的右孩子 // m: i节点为头的最大bst拓扑结构大小 -> m[i] // 返回: 以h为头的整棵树上,最大bst拓扑结构的大小 public static int maxBSTTopology(int h) { if (h == 0) { return 0; } int l = tree[h][1]; int r = tree[h][2]; int p1 = maxBSTTopology(l); int p2 = maxBSTTopology(r); int tmp = l; while (tmp < h && record[tmp] != 0) { tmp = tree[tmp][2]; } // 不用沿途修改所有节点的记录了 // 因为再往上遍历的节点,边界最多包括当前的头节点 + 左孩子 + 一直往左 // 所以只需要修改左孩子的边界即可 // 也就是说,从当前节点的左孩子的右孩子开始,一直往右的所有点都不会再遇到了 record[l] -= record[tmp]; tmp = r; while (tmp > h && record[tmp] != 0) { tmp = tree[tmp][1]; } // 不用沿途修改所有节点的记录了 // 因为再往上遍历的节点,边界最多包括当前的头节点 + 右孩子 + 一直往左 // 所以只需要修改右孩子的边界即可 // 也就是说,从当前节点的右孩子的左孩子开始,一直往左的所有点都不会再遇到了 record[r] -= record[tmp]; record[h] = record[l] + record[r] + 1; return Math.max(Math.max(p1, p2), record[h]); } }