题目:
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,最后可以遍历二叉树,记录每一层无左子树的结点的个数;
2.这里我的脑洞较大,万一有两个很远的亲戚结婚了呢,因此这个题目的意图就升级为图了,所以我用了图的BFS,类似于“六度空间”的思路,可以持续记录层次,(不过在实现过程中为了省时省力,我没设置Collected数组来判断是否已被收录,也还是没去解决亲戚结婚生子的可能性,不过还是通过了@@)。
3.采用邻接矩阵存储,因为结点是从1开始,这里我将G[V][0]用来记录子节点的个数;
接下来就是BFS,注意如何记录每个结点的对应的层数,要求还涉及队列的操作;
代码如下:
#include<stdio.h>
#include<stdlib.h>
#define Vertex int
#define MaxVNum 101
typedef struct GNode *MGraph;
struct GNode{
int Nv;
int Ne;
int G[MaxVNum][MaxVNum];
};
typedef struct VNode *PtrToVNode;
struct VNode{
Vertex V;
int ChildNum;
Vertex *Edge;
};
typedef struct QNode *Queue;
struct QNode{
int front;
int rear;
Vertex Q[MaxVNum];
};
MGraph BuiltGraph();
MGraph CreatGraph(int N);
void InsertEdge(MGraph G,PtrToVNode V,int j);
void Solve(MGraph G);
Queue CreatQ();
void AddQ(Queue Q,Vertex V);
Vertex DeleteQ(Queue Q);
bool IsEmpty(Queue Q);
int main()
{
MGraph G;
G=BuiltGraph();
Solve(G);
return 0;
}
MGraph BuiltGraph()
{
int N,M,i,j;
MGraph G;
PtrToVNode V=(PtrToVNode)malloc(sizeof(struct VNode));
scanf("%d %d",&N,&M);
G=CreatGraph(N);
for(i=0;i<M;i++)
{
scanf("%d %d",&V->V,&V->ChildNum);
V->Edge=(Vertex *)malloc(V->ChildNum *sizeof(Vertex));
for(j=0;j<V->ChildNum;j++)
{
scanf("%d",&V->Edge[j]);
InsertEdge(G,V,j);
}
}
return G;
}
MGraph CreatGraph(int N)
{
MGraph G=(MGraph)malloc(sizeof(struct GNode));
G->Nv=N;
Vertex V,W;
for(V=0;V<=N;V++)
for(W=0;W<=N;W++)
G->G[V][W]=0;
return G;
}
void InsertEdge(MGraph G,PtrToVNode V,int j)
{
G->G[V->V][0]=V->ChildNum;
G->G[V->V][V->Edge[j]]=1;
}
void Solve(MGraph G)
{
Queue Q;
Q=CreatQ();
Vertex V,W;
int Num[MaxVNum]={},level,i;
Vertex last,tail;
AddQ(Q,1);
last=tail=1;
level=1;
while(!IsEmpty(Q))
{
V=DeleteQ(Q);
if(G->G[V][0])
{
for(W=1;W<=G->Nv;W++)
{
if(G->G[V][W])
{
AddQ(Q,W);
tail=W;
if(G->G[W][0]==0)
Num[level+1]++;
}
}
}
else if(V==1)
Num[level]++;
if(V==last)
{
level++;
last=tail;
}
}
printf("%d",Num[1]);
for(i=2;i< level;i++)
printf(" %d",Num[i]);
printf("\n");
}
Queue CreatQ()
{
Queue Q=(Queue)malloc(sizeof(struct QNode));
Q->rear=Q->front=-1;
return Q;
}
void AddQ(Queue Q,Vertex V)
{
Q->Q[++ Q->rear]=V;
}
Vertex DeleteQ(Queue Q)
{
return Q->Q[++ Q->front];
}
bool IsEmpty(Queue Q)
{
return Q->front == Q->rear;
}