1004 Counting Leaves
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 0<N<100, the number of nodes in a tree, and M (<N), the number of non-leaf nodes. Then M lines follow, each in the format:
ID K ID[1] ID[2] ... ID[K]
where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 01.
The input ends with N being 0. That case must NOT be processed.
Output Specification:
For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.
The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.
Sample Input:
2 1 01 1 02 • 1 • 2
Sample Output:
0 1
题意
第一行给定一个 N NN 和 M MM ,分别表示该树的结点总数量以及非叶子结点数量。
接下来的 M MM 行,输入每个非叶子结点的孩子结点,格式为:
ID K ID[1] ID[2] ... ID[K]ID 表示非叶子结点的编号,K KK 表示该结点有 K KK 个孩子结点,然后紧跟 K KK 个孩子结点的编号。
让我们统计该树中每一层的叶子结点个数,并输出。
如下图所示,cnt 表示每一层的叶子结点数:
思路
- 用链式前向星的方法存储该树。
- 递归更新每层叶子结点的数量,因为题目给定根结点是
1
,所以从1
开始向下递归,去递归它的孩子结点。如果在递归过程中h[u] == -1
即结点u
没有孩子结点,则将该层的叶子节点数加1
。 - 最后输出每层的叶子结点数量。
代码
#include<bits/stdc++.h> using namespace std; const int N = 110; int h[N], ne[N], e[N], idx; //邻接表 int cnt[N]; //计算每一层的叶子结点数 int max_depth; //树的最大深度 //链式前向星,往a向b加一条边 void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } //递归更新每层的叶子结点数量 void dfs(int u, int depth) { //如果当前结点已经是叶子结点,则进行更新操作 if (h[u] == -1) { max_depth = max(max_depth, depth); cnt[depth]++; return; } //递归遍历其孩子结点 for (int i = h[u]; ~i; i = ne[i]) dfs(e[i], depth + 1); } int main() { int n, m; cin >> n >> m; //输入结点之间的关系 memset(h, -1, sizeof h); while (m--) { int a, b, k; cin >> a >> k; while (k--) { cin >> b; add(a, b); } } dfs(1, 0); //根结点为1 //输出每层的叶子结点数 cout << cnt[0]; for (int i = 1; i <= max_depth; i++) cout << " " << cnt[i]; cout << endl; return 0; }