家族树叶子节点统计
家族层次结构通常由谱系树表示。您的任务是统计每个辈分层级中没有孩子的家庭成员数量。
输入规范:
每个输入文件包含一个测试用例。每个用例以一行开始,包含 (树中的节点数)和 (非叶子节点的数量)。然后是 行,每行格式如下:
ID K ID[1] ID[2] ... ID[K]
其中 ID 是表示给定非叶子节点的两位数字,K 是其子节点的数量,后面是一个两位数字 ID 序列,表示其子节点。为简单起见,我们将根节点 ID 固定为 01。
输入以 N 为 0 结束。该情况不需要处理。
输出规范:
对于每个测试用例,您需要从根节点开始,统计每个辈分层级中没有孩子的家庭成员数量。这些数字必须在一行中打印,用空格分隔,行末不能有多余的空格。
样例表示一棵只有 2 个节点的树,其中 01 是根节点,02 是它唯一的子节点。因此,在根节点 01 层级上,有 0 个叶子节点;在下一层级,有 1 个叶子节点。所以我们应该输出 0 1
。
样例输入:
2 1
01 1 02
样例输出:
0 1
Solve
节点ID有两位数组成,可知节点数为 ,让我们输出每一行中的叶子节点个数。
故先存入图,由于存入时为先知道一个节点然后存其子节点,则可以在存入时使用 hasChild
来标记当前节点为有孩子,这样存完图后没有标记的就是有子节点的节点。
而之后使用 bfs 来进行层序遍历,核心思想为每轮遍历是当前层级的所有节点,同时为保证每个节点只访问一次,需要在加入队列时进行标记 visited
。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int main() {
int n, m;
while(cin >> n && n != 0) {
cin >> m;
vector<vector<int>> family(100);
vector<bool> hasChild(100, false);
while(m--) {
int parent, k;
cin >> parent >> k;
hasChild[parent] = true;
for(int i = 0; i < k; i++) {
int child;
cin >> child;
family[parent].push_back(child);
}
}
queue<int> q;
vector<bool> visited(100, false);
q.push(1);
visited[1] = true;
vector<int> res;
while(q.size()) {
int levelSize = q.size();
int levelLeaf = 0;
for(int i = 0; i < levelSize; i++) {
int current = q.front();
q.pop();
if(!hasChild[current])
levelLeaf++;
for(int children : family[current]) {
if(!visited[children]) {
visited[children] = true;
q.push(children);
}
}
}
res.push_back(levelLeaf);
}
for(int i = 0; i < res.size();i ++)
cout << res[i] << " \n"[i==res.size()-1];
}
return 0;
}