输入样例:
10
3 6 4 8
0
0
0
2 5 9
0
1 7
1 2
0
2 3 1
输出样例:
4
0 4 9 1
算法思路:
求树的从根节点开始的最长的路径,只要找到根结点的所有儿子结点为根结点的最长路径即可,找到时,记录该结点的儿子结点,两个二子结点路径相等时,找最小结点号的儿子,最后输出路径。
Java代码:
import java.io.*;
import java.util.Arrays;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static int ini() throws IOException {
st.nextToken();
return (int)st.nval;
}
static int n, maxdeep;
static final int N = 10005;
static int []e = new int[N];
static int []ne = new int[N];
static int []h = new int[N];
static int idx;
static int []son = new int[N];
public static void main(String[] args) throws IOException {
int n = ini();
Arrays.fill(h, -1);
boolean vis[] = new boolean[n];
Arrays.fill(son, -1);
for(int i = 0; i < n; i++) {
int k = ini();
while(k-- > 0) {
int t = ini();
vis[t] = true;
add(i, t);
}
}
int root = 0;
for(int i = 0; i < n; i++) // 找根结点
if(vis[i] == false) root = i;
System.out.println(dfs(root));
System.out.print(root);
for(int i = son[root]; i != -1; i = son[i])
System.out.print(" " + i);
}
public static int dfs(int u) { // 返回深度,求当前根的儿子结点的最大深度
int res = 0;
for(int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
int d = dfs(j); // 求每个儿子的深度
if(d > res) { // 比较每个儿子的最大深度
res = d; //
son[u] = j; // u的儿子结点为j
}else if(d == res) { // 深度一样时,选最小的序列号
son[u] = Math.min(j, son[u]);
}
}
return res + 1; // 递归到根结点时,加上自身的高度1
}
public static void add(int a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
}