PAT甲级刷题记录——1004 Counting Leaves (30分)

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 IDis a two-digit number representing a given non-leaf node, Kis 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 01is the root and 02is its only child. Hence on the root 01level, there is 0leaf node; and on the next level, there is 1leaf node. Then we should output 0 1in 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;
}
发布了54 篇原创文章 · 获赞 27 · 访问量 4971

猜你喜欢

转载自blog.csdn.net/weixin_42257812/article/details/105595076