我的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;
}