解法一:建树+广度优先遍历
设计好结点数据结构,边读入边建树,用 Map 保存结点防止重复创建同一编号的结点。建树后进行一次广度优先遍历计算每层的叶子结点数量。
import java.util.*;import java.io.*;public class Main {public static void main(String[] args) throws IOException {StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));in.nextToken();int N = (int) in.nval;in.nextToken();int M = (int) in.nval;// 处理特殊情况if (M == 0) {out.println(N);out.flush();return;}// 建树Map<Integer, TreeNode> map = new HashMap();for (int i = 0, id, cnt; i < M; ++i) {in.nextToken();id = (int) in.nval;in.nextToken();cnt = (int) in.nval;TreeNode root = map.getOrDefault(id, new TreeNode(id, cnt));for (int j = 0, childId; j < cnt; ++j) {in.nextToken();childId = (int) in.nval;TreeNode childNode = map.getOrDefault(childId, new TreeNode(childId));map.put(childId, childNode);root.next.add(childNode);}map.put(id, root);}// 层序遍历Queue<TreeNode> queue = new LinkedList<>();queue.offer(map.get(1));ArrayList<Integer> ans = new ArrayList<>();while (!queue.isEmpty()) {int cnt = 0;int size = queue.size();for (int i = 0; i < size; ++i) {TreeNode root = queue.poll();if (root.next.isEmpty()) {++cnt;} else {for (TreeNode node : root.next) {queue.offer(node);}}}ans.add(cnt);}for (int i = 0; i < ans.size() - 1; ++i) {out.print(ans.get(i) + " ");}out.println(ans.get(ans.size() - 1));out.flush();}}class TreeNode {int id;List<TreeNode> next;TreeNode(int id) {this.id = id;next = new ArrayList<>();}TreeNode(int id, int capacity) {this.id = id;next = new ArrayList<>(capacity);}}
