这道题的思路是维护一个树,然后对其进行遍历,统计每一层的叶子节点个数。
1.如何维护一个树?
考虑使用邻接表来存储一课树。而邻接表可看出n个单链表组成。先定义单链表(链表中的元素都是头节点的子节点)。我们用两个数组来维护单链表,分别是val[],next[],二者用数组下标相关联。下面举个例子。第0个节点的val是3,则val[0]=3,他的下一个节点是第1个节点,则next[0]=1,第一个节点为4,则val[1]=4,next[1]=2,以此类推。
下一步就是如何建立单链表,可以使用头插法的方式,假设我们要存储值为6节点。则
val[未使用的数组下标x]=6,next[x]=head,head=x;
最后就是n个单链表的组合,我们可以用h[]保存n个单链表的头节点。就可以存储一颗树了。
2.统计每一层的叶子节点个数,考虑使用dfs。
深度优先遍历,用一个数组统计每一层叶子节点个数即可。代码如下
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int n,m;
int h[N],val[N],ne[N],idx;//next属于保留字,不能使用;idx是未使用的数组下标。类似于尾指针
int cnt[N],max_depth;
void add(int a,int b){//头插法
val[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u,int depth){
if(h[u]==-1){//叶子节点
cnt[depth]++;//cnt[]维护depth层的叶子节点个数
max_depth=max(depth,max_depth);//记录最大深度
}
for(int i=h[u];~i;i=ne[i])//递归遍历h[u]的子节点
dfs(val[i],depth+1);
}
int main(){
cin>>n>>m;
memset(h,-1,sizeof h);//邻接表,初始所有的链表为空。
for(int i=0;i<m;i++){
int id,k;
cin>>id>>k;
while(k--){
int son;
cin>>son;
add(id,son);//将son放入id的链表之中,即son是id的子节点
}
}
dfs(1,0);
cout<<cnt[0];
for(int i=1;i<=max_depth;i++) cout<<" "<<cnt[i];
cout<<endl;
return 0;
}