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 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
题目大意是让我们统计每一层树中没有子节点的节点个数,N为节点总数,M为非叶节点总数,接着M行数据,每行数据开头为当前节点,第二个数据为子节点数,后面跟着的都是子节点。题目就是这样,坑还是有一些的,我就是被坑得不浅。。
1.当N为1,M为0时,输出1,否则测试点2过不了
2.子节点可能在父节点之前开始输出,也就是说输入并不是按照节点顺序输入的,我的程序也因此产生了混乱。因为如果按照顺序的话,之前没有出现过的节点只有可能是根节点,所以这样的测试数据让我的程序以为有好几个根节点。如果这里没有注意到的话测试点1和测试点3是过不了的。
再说我的思路,我是用vector数组来储存树的,每个节点都储存有它的父节点位置,也就是在数组中的位置,输入完成后一棵家族树也就构建完成了,要完成题目无非要获取到两个必要信息,每个节点位于哪一层和每个节点的子节点数量,每个节点的子节点数在构建树的时候已经统计完成,剩下的就是得到每个节点位于哪一层。这里我采用递归,从当前节点向前递归,在父节点索引为-1的时候则停止,说明一下,我规定根节点的父节点索引为-1,因为在这个数组里不可能找到根节点的父节点。
代码比较丑,因为刚开始没想到这些坑,后来改着改着就变丑了。。不过时间复杂度还是可以的,可能只是因为题目,没有在这里为难我们吧,代码如下,以后有空再慢慢修改
#include<iostream>
#include<vector>
#include<string>
using namespace std;
struct Node
{
int fatherIndex;
string name;
int childNumber;
int level;
};
vector<Node> familyTree;
int travelTree(Node &node)
{
if (node.fatherIndex != -1)
{
node.level = travelTree(familyTree[node.fatherIndex]) + 1;
return node.level;
}
else if(node.fatherIndex==-1)
{
node.level = 0;
return 0;
}
}
int main()
{
int N, M;
cin >> N >> M;
if (N == 0)
{
return 0;
}
if (N == 1 && M == 0)
{
cout << 1;
system("pause");
return 0;
}
for (int i = 0; i < M; i++)
{
string name;
cin >> name;
int count = 0;
int index = 0;
for (int j = 0; j < familyTree.size(); j++)
{
if (name == familyTree[j].name)
{
index = j;
count++;
break;
}
}
if (count == 0)
{
int childNumber = 0;
cin >> childNumber;
Node node;
node.childNumber = childNumber;
node.name = name;
node.fatherIndex = -1;
familyTree.push_back(node);
index = familyTree.size()-1;
for (int k = 0; k < childNumber; k++)
{
Node node;
cin >> node.name;
int flag = 0;
for (int m = 0; m < familyTree.size(); m++)
{
if (node.name == familyTree[m].name)
{
familyTree[m].fatherIndex = index;
flag++;
break;
}
}
if (flag > 0)
{
continue;
}
node.childNumber = 0;
node.fatherIndex = index;
familyTree.push_back(node);
}
}
else if (count != 0)
{
int childNumber = 0;
cin >> childNumber;
familyTree[index].childNumber = childNumber;
for (int k = 0; k < childNumber; k++)
{
Node node;
cin >> node.name;
int flag = 0;
for (int m = 0; m < familyTree.size(); m++)
{
if (node.name == familyTree[m].name)
{
familyTree[m].fatherIndex = index;
flag++;
break;
}
}
if (flag > 0)
{
continue;
}
node.fatherIndex = index;
node.childNumber = 0;
familyTree.push_back(node);
}
}
}
int maxLevel = 0;
for (int i = familyTree.size() - 1; i >= 0; i--)
{
familyTree[i].level=travelTree(familyTree[i]);
if (maxLevel < familyTree[i].level)
{
maxLevel = familyTree[i].level;
}
}
for (int i = 0; i <=maxLevel; i++)
{
int count = 0;
for (int j = 0; j < familyTree.size(); j++)
{
if (familyTree[j].level == i && familyTree[j].childNumber == 0)
{
count++;
}
}
cout << count;
if (i != maxLevel)
{
cout << " ";
}
}
system("pause");
return 0;
}
附上几个测试用例:
case 1:
输入:
9 5
06 1 09
01 2 02 03
02 1 04
04 1 08
03 3 05 06 07
输出:
0 0 2 2
case 2:
输入:
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