1004 Counting Leaves (30 分)-PAT甲级

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

 题目大意:给定一颗多叉树,求出它每一层对应的叶子结点数并输出。

 思路:写了1021 Deepest Root (25 分)-PAT甲级这个题,回过头来看这道题好像也没有那么难了。(心得:遇到不会的题可以先跳过,等会了再回头做,而不必想来想去不得答案还浪费了时间)

1.本题涉及多叉树的存储,用vector二维数组存,然后进行深度优先搜索(DFS),DFS实现的时候要记录当前遍历到的深度depth,对当前深度depth的叶结点进行统计(这里使用的是关联容器map,可以实现自动排序),最后按照多叉树深度递增的顺序输出每一层的叶子结点数即可。

2.当然也可以用广度优先搜索(BFS)来遍历多叉树,只不过比深度优先搜索要复杂一些,不过这也不是什么大问题,关键在于如何得知当前所在深度。怎么记录所在深度呢?用三个状态变量来实现:cur_depth(当前层次还没有遍历的结点个数),next_depth(下一层次要遍历的结点个数),depth(当前所在深度)。每遍历一个当前层次的结点,cur_depth就自减一,每次入队列一个结点,next_depth就自增1,当cur_depth为0时,就说明当前层次已经遍历完,就进入遍历下一层次,depth自然就增加1,cur_depth=next_depth(更新cur_depth),队列为空就说明遍历完成。

刷题心得: 1.利用DFS或BFS对多叉树进行遍历时不需要额外的visited数组用于标明结点访问状态,原因在于多叉树的结构特点(不会重复遍历)

2.map容器的使用注意事项之一:定义了一个map容器对象m后,m[key]不能单独作为语句,但是放在if语句中却是正确的:如if(m[key])

 AC代码(深度优先搜索DFS版本)

#include <iostream>
#include <vector>
#include <map>
using namespace std;
vector<vector<int>> tree;
map<int,int>cnt;
void dfs(int cur,int depth)
{
	if(!cnt[depth])
		cnt[depth]=0;
	if(tree[cur].empty()) 
	{
		cnt[depth]++;
		return;
	}
	for(int i=0;i<tree[cur].size();i++)
		dfs(tree[cur][i],depth+1);
}
int main()
{
	int n,m,temp1,temp2,k;
	cin>>n>>m;
	tree.resize(n+1);
	for(int i=0;i<m;i++) 
	{
		cin>>temp1>>k;
		for(int j=0;j<k;j++)
		{
			cin>>temp2;
			tree[temp1].push_back(temp2);
		}
	}
	dfs(1,1);
	map<int,int>::iterator it;
	for(it=cnt.begin();it!=cnt.end();it++)
	{
		if(it!=cnt.begin())
			cout<<" ";
		cout<<it->second;
	}
	return 0;
}

 附广度优先搜索BFS版本

#include <iostream>
#include <vector>
#include <map>
#include <queue> 
using namespace std;
vector<vector<int>> tree;
map<int,int>cnt;
void bfs(int cur,int depth)
{
	queue<int>q;
	q.push(cur);
	int cur_depth,next_depth;
	cur_depth=1;
	next_depth=0;
	while(!q.empty())
	{
		if(!cnt[depth])
			cnt[depth]=0;
		if(tree[q.front()].size()==0)
			cnt[depth]++;
		for(int i=0;i<tree[q.front()].size();i++)
		{
			q.push(tree[q.front()][i]);
			next_depth++;
		}
		q.pop();
		cur_depth--;
		if(cur_depth==0)
		{
			cur_depth=next_depth;
			next_depth=0;
			depth++;
		}
	}
	return;
}
int main()
{
	int n,m,temp1,temp2,k;
	cin>>n>>m;
	tree.resize(n+1);
	for(int i=0;i<m;i++) 
	{
		cin>>temp1>>k;
		for(int j=0;j<k;j++)
		{
			cin>>temp2;
			tree[temp1].push_back(temp2);
		}
	}
	bfs(1,1);
	map<int,int>::iterator it;
	for(it=cnt.begin();it!=cnt.end();it++)
	{
		if(it!=cnt.begin())
			cout<<" ";
		cout<<it->second;
	}
	return 0;
}

更多PAT甲级题解,请访问:PAT甲级刷题之路--题目索引+知识点分析(正在进行),感谢支持!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值