目录
题目:
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
Input
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.
Output
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
题目大意:通过告诉亲子关系的方式给定一棵树,然后输出每一层的叶节点个数
分析:
可知亲子关系对最终的结果影响不是很大,但由于中间的过程计数还是需要记录部分亲子关系
所以我完全没有建树,而是直接记录了每个节点的层数和该层的叶节点数,节点层数由父节点层数+1得到
反思:
一开始1,3测试点一直过不去
后来发现是因为测试样例可能不是按顺序给的,即:一个节点先于他的父节点被录入
如果是这样,那此时父节点的层数就是未知数,会出现混乱
改进方法:若给定节点的父节点此时未被记录,则定义该节点的层数为100+父节点编号,然后后面再集中处理这些层数大于100的节点。
推荐测试用例:
11 5
5 2 10 7
1 3 5 3 4
3 1 9
10 1 2
9 3 11 12 13
输出:0 1 1 4
代码:
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<map>
#include<list>
#include<set>
using namespace std;
int main()
{
int n, m, i, j, k, father, ID, flag = 0;
set<int> f;
int number[100] = { 1 };//一开始根节点有一个节点,后续树还未建
map<int, int> tree;
tree[1] = 0;//ID为01的点在第0层
cin >> n >> m;
for (i = 0; i < m; i++)//开始建树
{
flag = 0;
cin >> father >> k;
if (tree.count(father))flag = 1;
for (j = 0; j < k; j++)
{
cin >> ID;
if (flag&&tree[father]<100)//父节点已存在
{
number[tree[father] + 1]++;//若孩子不重复,则在孩子层number++
tree[ID] = tree[father] + 1;//记录孩子的层数为父亲层数+1
}
else tree[ID] = father + 100;
}
if (flag&&tree[father] < 100)number[tree[father]]--;//因为父亲节点非叶节点,所以在父节点层number--
}
for (map<int, int>::iterator it = tree.begin(); it != tree.end(); it++)//集中处理层数>100的节点
{
while (it->second > 100)//修正直到该节点的层数为正确值
{
father = it->second % 100;
ID = it->first;
while (tree[father] > 100)//因为该节点的父节点可能层数也>100,所以先找到一个层数<100的祖先节点
{
ID = father;
father = tree[ID] % 100;
}
f.insert(father);
tree[ID] = tree[father] + 1;
number[tree[ID]]++;
}
}
while (f.size())//将层数曾经>100的父节点所在层叶节点数--
{
number[tree[*f.begin()]]--;
f.erase(f.begin());
}
m = n - m;
for (i = 0; m; i++)//输出
{
if (i)cout << ' ';
cout << number[i];
m -= number[i];
}
return 0;
}