题意
- 给定家族树(结点总数、非叶节点总数和上下层对应关系),求每层的叶节点数。
注意
- 输入数据后从根节点递归得到每个节点的层次。(因为某些测试用例不是严格按照树层次输入的,不这样搞会挂掉一些测试点)
- 4月10日更新:这道题很简单,可以用
bfs
也可以用dfs
来遍历家族树,从而确定每个结点层次。 - 使用
dfs
的话需要注意在每个父节点的函数里给它的子节点赋值(特殊地,根节点的层次值在最外面调用dfs
之前赋予),因为当前节点的层次值需要用到其父节点的层次值,所以不好在当前结点函数里给自己赋值,那样还得多传一个参数。可以对比这个里面dfs
的写法,体会在当前结点处理自己还是处理子节点。
单词
- pedigree 血统,家谱
- hierarchy 层次
- fix 固定
代码
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX = 100;
int n, m;
struct P
{
int K;
int child[MAX];
int H;
};
P p[MAX];
void count()
{
int a[MAX] = { 0 };
int max_H = -1;
for (int i = 1; i <= n; i++)
{
if (p[i].K == 0)
a[p[i].H]++;
max_H = max(max_H, p[i].H);
}
for (int i = 0; i <= max_H; i++)
{
if (i == max_H)
printf("%d", a[i]);
else printf("%d ", a[i]);
}
}
void dfs(int root)
{
if (p[root].K == 0)
return;
for (int i = 0; i < p[root].K; i++)
{
p[p[root].child[i]].H = p[root].H + 1;
dfs(p[root].child[i]);
}
}
void bfs(int root)
{
queue<int> q;
q.push(root);
p[root].H = 0;
for (; !q.empty();)
{
int x = q.front();
q.pop();
for (int i = 0; i < p[x].K; i++)
{
p[p[x].child[i]].H = p[x].H + 1;
q.push(p[x].child[i]);
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
p[i].K = 0;
int pp;
for (int i = 0; i < m; i++)
{
scanf("%d", &pp);
scanf("%d", &p[pp].K);
for (int j = 0; j < p[pp].K; j++)
scanf("%d", &p[pp].child[j]);
}
p[1].H = 0;
dfs(1);
count();
return 0;
}