解题思路
题目以家谱树为背景,真实的目的是以层为单位,计算叶子结点的数目。虽然考察的是树的相关内容,但是不需要建树。只需要借用层次遍历的思路就可以确定每个结点所属的层。然后使用哈希表在输入的时候标记非叶结点,剩下的就是叶子结点。
AC代码
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
vector<int> adj[101];
int hashtable[101] = {0};
int pos[101] = {0}; // 记录下标对应的结点的层
vector<int> output; // 记录下标对应的层的叶子结点的数目
int main() {
int n, m;
scanf("%d %d", &n, &m);
output.resize(n + 1);
for (int i = 0; i < m; ++i)
{
int id, k;
scanf("%d %d", &id, &k);
hashtable[id] = 1;
for (int i = 0; i < k; ++i) {
int temp;
scanf("%d", &temp);
adj[id].push_back(temp);
}
}
pos[1] = 1;
queue<int> q;
q.push(1);
int level = 0;
while(!q.empty()) {
int p = q.front();
q.pop();
for (int i = 0; i < adj[p].size(); ++i) {
q.push(adj[p][i]);
pos[adj[p][i]] = pos[p] + 1;
if (level < pos[p] + 1)
level = pos[p] + 1;
if (hashtable[adj[p][i]] == 0)
output[pos[adj[p][i]]]++;
}
}
if (n == 1) printf("1\n"); // 特判,如果只有一个结点
else if (n != 1 && n != 0){
printf("0 ");
for (int i = 2; i <= level; ++i) {
printf("%d%s", output[i], i == level ? "\n" : " ");
}
}
return 0;
}