我的PAT系列文章更新重心已移至Github,欢迎来看PAT题解的小伙伴请到Github Pages浏览最新内容。此处文章目前已更新至与Github Pages同步。欢迎star我的repo。
题目
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 , the number of nodes in a tree, and ( ), the
number of non-leaf nodes. Then 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 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
思路
虽然是30分的题,但是好像比1003还简单。
同样使用了邻接链表(adjacent list),数据结构如下:
- Member(Vertex):表示一个家庭成员,我使用了两个结构成员:
- level,表示这个人在家谱中的辈分,最高的辈分是0,辈分越低,level越大
- child,指向Child结构变量,即链表的第一个节点
- Child(Edge):表示亲子关系,也使用了两个结构成员:
- ID,表示这个孩子的ID
- iter,指向相同父母的下一个孩子Child变量
读取数据,建立邻接链表。初始化01节点的level为0,其他level为INF。
然后按level从0开始,依次遍历所有Member,找出相应辈分的家庭成员。这时分两种情况:这个成员没有孩子,那么需要进行计数;这个成员有孩子,那么需要更新他们的level值为这个成员的level+1,以便下一次遍历时找到他们。
使用一个标记表明何时不需再遍历,我用的是记录人数,当之前所有level的人数已经是总人数,那么说明已全部遍历,此时退出循环。
代码
最新代码@github,欢迎交流
#include <stdio.h>
#define MAX 999
typedef struct Member *Member;
typedef struct Child *Child;
struct Member{
int level;
Child child;
};
struct Child{
int ID;
Child iter;
};
int main()
{
int N, M, ID, cID, K;
struct Member nodes[100];
struct Child children[100];
/* Read data and initiate a adjacent list */
scanf("%d %d", &N, &M);
for(int i = 1; i <= N; i++)
{
nodes[i].level = MAX;
nodes[i].child = NULL;
}
nodes[1].level = 0; /* root node at level 0 */
for(int i = 0, k = 0; i < M; i++)
{
scanf("%d %d", &ID, &K);
for(; K--; k++)
{
scanf("%d", &cID);
children[k].ID = cID;
children[k].iter = nodes[ID].child;
nodes[ID].child = &children[k];
}
}
/* For every level, find leaf nodes */
int n = N, count;
for(int level = 0; n; level++)
{
count = 0;
for(int i = 1; i <= N; i++) if(nodes[i].level == level)
{
n--;
if(nodes[i].child == NULL)
count++;
/* set the children to next level */
for(Child c = nodes[i].child; c; c = c->iter)
nodes[c->ID].level = level + 1;
}
printf("%d%c", count, n ? ' ' : '\0');
}
return 0;
}