【PAT甲级题解记录】1004 Counting Leaves (30 分)

【PAT甲级题解记录】1004 Counting Leaves (30 分)

前言

Problem:1004 Counting Leaves (30 分)

Tags:树的DFS

Difficulty:剧情模式 想流点汗 想流点血 死而无憾

Address: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.

有一棵树,节点编号 01~99 ,求从根节点所在层开始按顺序所有层的叶子节点数量。

解题思路

  1. 其实算是树的遍历,但不需要花心思写太多数据结构,只需要拿一个二维数组去存取每一个节点的子节点集合。
  2. 遍历方法可以采取递归dfs较为简单,搜索到叶子节点时对相应层的叶子数累加即可。
  3. 才知道 ‘01’ 这种作为整型输入时可以直接输入为1。

参考代码

/*
 * @Author: Retr0.Wu 
 * @Date: 2022-02-13 00:23:45 
 * @Last Modified by: Retr0.Wu
 * @Last Modified time: 2022-02-13 00:58:09
 */
#include <bits/stdc++.h>
using namespace std;
vector<int> cnt(100);  // 存储每一层的叶子结点数量(最多100个点自然最多100层)
vector<int> son[100];  // 存储每一个节点的子结点集合
int maxdepth;
void dfs(int father,int depth)
{
    
    if(son[father].empty()){  // 是一个叶子结点,该层cnt++
        cnt[depth]++;
        maxdepth = max(maxdepth,depth);  // 只在叶子结点处需要判断,有子节点的肯定子节点深度更深所以不用max()
    }
    else{  // 否则往下遍历
        for(int i=0;i<son[father].size();i++){
            dfs(son[father][i],depth+1);  // 千万不要depth++/++depth不然depth在这个循环里会一直变大
        }
    }
}
int main()
{
    int N, M; // 100
    cin>>N>>M;
    for (int i = 0; i < M; i++)
    {       
        int ID,K;
        cin>>ID>>K;  // 01 这种形式也可以直接当整数输入变成 1 
        for(int j=0;j<K;j++){
            int idi = 0;
            cin>>idi;
            son[ID].push_back(idi);
        }
    }
    dfs(1,0);
    for(int i=0;i<=maxdepth;i++){  
        if(i>0) cout<<" ";
        cout<<cnt[i];
    }



    return 0;
}

如果想将id作为字符串处理,可以这么写:

#include<iostream>
#include<vector>
#include<map>

using namespace std;
int N; // number of nodes (100)
int M; // the number of non-leaf nodes
map<string, vector<string>> tree;
vector<int> leaf_num(100, 0);
int MAX_level;

void init() {
    cin >> N >> M;
    for (int i = 0; i < M; ++i) {
        string id;
        int k;
        cin >> id >> k;
        vector<string> children(k);
        for (int j = 0; j < k; ++j) {
            cin >> children[j];
        }
        tree[id] = children;
    }
}

void dfs(string root, int depth) {
    if (tree.count(root)) {
        vector<string> children = tree[root];
        for (int i = 0; i < children.size(); i++) {
            dfs(children[i], depth + 1);
        }
    } else {
        leaf_num[depth]++;
        MAX_level = max(MAX_level, depth);
    }
}

void solution_1004() {
    init();
    dfs("01", 0);
    for (int i = 0; i <= MAX_level; i++) {
        if (i > 0)cout << " ";
        cout << leaf_num[i];
    }
    cout << endl;
}
int main() {
    solution_1004();
    return 0;
}

总结

简单的树的深搜。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值