一. 题目描述
https://vjudge.net/problem/UVA-548
二. 解题思路
- 根据树的中序遍历,后序遍历构建出完整的树。后序遍历使得根节点在最后一个字符,得到根节点后,到中序遍历中找到并将树分为左右子树,再递归调用,构建出完整的树。
- 再用DFS对树进行遍历,找出叶子节点距根节点的权重之和最小的那个叶子节点,保存最后输出该结点的权重。
- 注意:in.hasNextLine()输出结束后要及时退出,不然总数RE!坑死我了。
三. 解题代码
import java.util.Scanner;
public class Main{
static final int MAXV = 10000;
static int[] inorder = new int[MAXV];
static int[] postorder = new int[MAXV];
static int[] lch = new int[MAXV];
static int[] rch = new int[MAXV];
static int bs = Integer.MAX_VALUE;
static int n;
public static void main(String[] args) {
while (readLine(inorder)) {
readLine(postorder);
// in.close();
builTree(0, n - 1, 0, n - 1);
dfs(postorder[n - 1], 0);
System.out.println(best);
bs = Integer.MAX_VALUE;
best = Integer.MAX_VALUE;
}
in.close();
}
private static int builTree(int il, int ir, int pl, int pr) {
if (il > ir) {
return 0;
}
int root = postorder[pr];
int p = il;
while (inorder[p] != root) {
p++;
}
int count = p - il;
lch[root] = builTree(il, p - 1, pl, pl + count - 1);
rch[root] = builTree(p + 1, ir, pl + count, pr - 1);
return root;
}
static int best = Integer.MAX_VALUE;
private static void dfs(int wet, int sum) {
sum += wet;
if (lch[wet] == rch[wet] && rch[wet] == 0) {
if (sum < bs || (sum == bs && wet < best)) {
best = wet;
bs = sum;
}
}
if (lch[wet] != 0)
dfs(lch[wet], sum);
if (rch[wet] != 0)
dfs(rch[wet], sum);
}
static Scanner in = new Scanner(System.in);
private static boolean readLine(int[] order) {
if(!in.hasNextLine()){
return false;
}
n = 0;
String ns = in.nextLine();
// System.out.println(ns);
String[] nns = ns.split(" ");
for (int i = 0; i < nns.length; i++) {
order[n++] = Integer.parseInt(nns[i]);
}
return n > 0;
}
}