PTA 1004 Counting Leaves
题目翻译
族谱通常能够显示一个人在家族中的辈分。你的任务是计算一个家族中没有孩子的成员的数量。
输入格式
每一个输入文件包含一个测试样例。每一个样例由一行包括0<N<100,树中节点的个数,和M(<N),非叶节点的个数。然后接下来的M行的格式如下:
ID K ID[1] ID[2] ... ID[K]
ID
是一个两位数,代表给定的非叶子节点,K
是它的孩子的数量,紧接着是一个代表其孩子的两位数的ID
序列。为了简单起见,让我们把根节点的ID设为01
。
输入以N为0结尾。那个样例不用处理。
输出样例
对于每一个测试样例,你都应该计算从根节点开始每一层中没有孩子的节点的个数。成员们必须被输出在一行,由空格分隔开并且行尾没有多余的空格。
样例展示一个只有两个节点的数,01
是根节点并且02
是它唯一的孩子。因此在根01
层有0
个叶子节点;然后在下一层有1
个叶子节点。所以我们应该在一行输出0 1
。
样例输入
2 1
01 1 02
样例输出
0 1
分析:这道题大意就是给出了一棵树,N和M分别代表树的节点个数和非叶节点个数,然后依次输入每个非叶节点的编号和它的孩子的个数以及每一个孩子的编号。最后你需要输出每一层中叶子节点的个数。
很显然,这是一道关于树的遍历的题目,只不过题上并没有说是二叉树,所以很可能会出现一个节点有多于2个孩子的情况。这时我们只能选择用类似于存储图的方式来存储树了,鉴于题目问的是非叶节点的个数,显然用邻接表更方便一点。访问方式用BFS和DFS都可以,不过我个人觉得DFS写起来更顺手点,不过时间上可能没有BFS快。我用两种方法都写了一遍,AC代码如下。
DFS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> v[100]; //用来存储树的二维数组,用vector可以方便地得到每一行的长度
int maxDepth; //记录最大深度,输出的时候可以作为边界
int cot[100]; //记录每一层的非叶节点个数
void dfs(int node, int depth);
int main()
{
int n, m;
cin >> n >> m;
//用两重循环读取整棵树
for (int i = 0; i < m; i++)
{
int node, k;
cin >> node >> k;
for (int i = 0; i < k; i++)
{
int child;
cin >> child;
v[node].push_back(child);
}
}
dfs(1, 0);
for (int i = 0; i < maxDepth; i++)
cout << cot[i] << " ";
cout << cot[maxDepth];
return 0;
}
void dfs(int node, int depth)
{
//递归基,通过判断节点所在行的长度来判断是否是叶节点
if (v[node].size() == 0)
{
cot[depth]++;
maxDepth = max(maxDepth, depth);
return;
}
//用DFS遍历节点的所有子节点
for (int i = 0; i < v[node].size(); i++)
dfs(v[node][i], depth + 1);
}
BFS
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
int number;
int level;
node(int num, int lel)
{
number = num;
level = lel;
}
};
vector<int> v[100];
int cot[100];
int maxDepth;
void bfs();
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int t, k;
cin >> t >> k;
for (int i = 0; i < k; i++)
{
int child;
cin >> child;
v[t].push_back(child);
}
}
bfs();
for (int i = 0; i < maxDepth; i++)
cout << cot[i] << " ";
cout << cot[maxDepth];
}
void bfs()
{
queue<node> q;
node root(1, 0);
q.push(root);
while (!q.empty())
{
node t = q.front();
q.pop();
if (v[t.number].size() == 0)
{
cot[t.level]++;
maxDepth = max(t.level, maxDepth);
continue;
}
for (int i = 0; i < v[t.number].size(); i++)
{
node child(v[t.number][i], t.level + 1);
q.push(child);
}
}
}