1004 Counting Leaves (30 分)

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

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

code

#include
#include 
using namespace std;

vector<int> G[101];//邻接表存树
int leaf[101] = {0};//每层叶子结点数
bool vis[101] = {false};
int maxHeight = 0;//

void dfs(int node,int height)//遍历树的两种方式 DFS BFS
{
    vis[node] = true;
    if(height>maxHeight){
        maxHeight = height;
    }
    if(G[node].size()==0) {
        leaf[height]++;
    }
    for(int i = 0; i < G[node].size(); ++i){
       if(!vis[G[node][i]])
            dfs(G[node][i],height+1);
    }
}


int main()
{
    int n,m,ID,k,node;
    scanf("%d%d",&n,&m);
    for(int i = 0;i < m; ++i){
        scanf("%d%d",&ID,&k);
        for(int j = 0; j < k; ++j){
            scanf("%d",&node);
            G[ID].push_back(node);
        }
    }
    dfs(1,0);//
    for(int i = 0; i <= maxHeight; ++i){//
        if(i) printf(" ");
        printf("%d",leaf[i]);
    }
    printf("\n");
    return 0;
}


解题思路

  • 邻接表存储树,一个leaf[]数组表示每层的叶子结点数,vis[]表示当前节点是否已访问
  • 注意题目中虽然有 The input ends with N being 0. That case must NOT be processed. 以及 For each test case, you are supposed to… 这些话,但实际上每个test只包含一个case,如果你写了处理多个case的代码,会超时…btw这应该是题目的问题吧(大雾)
  • 关于dfs:
    • 两个参数,node表示当前节点,height表示当前层数,也即是当前节点的深度
    • 此dfs的两个任务:
    1. 寻找每一层的叶节点数
    2. 找到树的高度(因为最终要输出每一层的叶节点数,因此要确定树的层数)

note

  • 树的高度可从0开始,也可从1开始
  • 因为邓公的教材里规定只有根节点的树高度为0,因此为了统一 ;如果从1开始的话,改以下即可:
//初始化树高为0
int maxHeight = 0;
//从0层开始遍历
dfs(1,0);
//注意这里要遍历到maxHeignt,否则会少一层
for(int i = 0; i <= maxHeight; ++i){
       if(i) printf(" ");
       printf("%d",leaf[i]);
   }
  • 遍历方式有如上代码中的使用一个vis数组:这里vis[101]数组是一维的,对每个节点的编号进行访问;还可以设置二维数组vis[101][101]:对节点按位置访问,在此题中是一样的。

  • 另一种DFS遍历方式(参考算法笔记):

void dfs(int node,int height)
{
    if(height>maxHeight){
        maxHeight = height;
    }
    if(G[node].size()==0) {
        leaf[height]++;
        return;
    }
    for(int i = 0; i < G[node].size(); ++i){
        dfs(G[node][i],height+1);
    }
}

你可能感兴趣的:(PAT)