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
Sample Output:
0 1
思路
这个题目的思路很简单,就是用DFS或者BFS进行搜索(我这里用了DFS),如果是叶子结点那就返回,并且给对应的level[当前叶子结点的层数]++,如果不是叶子结点,那么寻找它的所有孩子结点,先处理孩子结点的层数,并且更新最大层数maxlevel的值,然后再对每个孩子结点进行DFS搜索。搜索结束之后,按顺序输出数组level的值即可。
这题有个小坑,就是输入的时候可能是无序的情况,比如现在这种情况:
非叶结点显然是01和03,如果按层序输入01和03的话,那么我相信绝大部分的代码都没问题,都能AC,但是这题它没说,也就是说,可能存在输入时是无序的情况(这里提醒一下自己:如果碰到部分正确的情况,就把测试数据倒过来输入试试看,很多时候都是没有考虑到无序的情况才导致的WA),也就是先输入03再输入01,因此,我们在规定每个结点的层次大小的时候,并不能在输入数据时就规定好(只有正序的情况下才能在输入数据时处理好,否则输入先来个子结点,那子子结点的层数是子结点的层数加1,这是没问题的,但是子结点本身的层数又是多少呢?这就无从得知了)。
所以我们在输入数据的时候应当是只处理结点之间的父子关系,然后在进行DFS搜索时,再处理父亲孩子之间层数的关系(所有数据存储完之后再处理层次就不会出错了,无论是乱序输入还是正序输入)。
代码
#include<cstdio>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
const int maxn = 1010;
struct node{
int deep;
vector<int> child;
node(){
deep = 1;
child.clear();
}
}Node[maxn];
vector<int> node[100];//记录当前结点和孩子结点
int level[maxn] = {0};//用于存放当前层的叶子结点数
void dfs(int id, int &maxlevel){
if(Node[id].child.size()==0){//size为0就说明没孩子,即叶子结点
level[Node[id].deep]++;//当前层的叶子数目+1
return;
}
for(int i=0;i<Node[id].child.size();i++){
Node[Node[id].child[i]].deep = Node[id].deep + 1;//孩子的deep是父亲的deep+1
if(Node[Node[id].child[i]].deep>maxlevel) maxlevel = Node[Node[id].child[i]].deep;//更新最大深度
dfs(Node[id].child[i], maxlevel);//dfs每个孩子
}
}
int main(){
int N, M;
scanf("%d%d", &N, &M);
if(N==0) return 0;
Node[1].deep = 1;//初始化根结点
Node[1].child.clear();
int maxlevel = 1;
while(M--){
int id, k;
scanf("%d%d", &id, &k);
while(k--){
int tmpid;
scanf("%d", &tmpid);
Node[id].child.push_back(tmpid);//放入孩子结点
}
}
dfs(1, maxlevel);
for(int i=1;i<=maxlevel;i++){
if(i==1) printf("%d", level[i]);
else printf(" %d", level[i]);
}
return 0;
}