7-25 小字辈(树bfs,和图一样 求深度即层数)

题目详情 - 7-25 小字辈 (pintia.cn)

7-25 小字辈

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。

输入格式:

输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。

输出格式:

首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。

输入样例:

9
2 6 5 5 -1 5 6 4 7

输出样例:

4
1 9

还是图bfs,dfs

而处理变成了

求深度:dis[v] = dis[u] + 1 :dis[v]:v点到起点的距离/v点的层数 u点同理

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10,INF = 0x3f3f3f3f;
vector<int> st[N];
int dis[N];//dis[i] i点的深度
int n;
//bfs 求深度 即  dis[v] = dis[father] + 1;
int bfs(int u) //bfs 人家只看有边的/只看集合/只看树 图
{
    memset(dis,INF,sizeof(dis));
    queue<int> q;
    q.push(u);
    dis[u] = 1;
    int maxdist = 1;    //只有祖宗自己情况
    while(!q.empty())
    {
        int father = q.front();
        q.pop();
        for(auto v:st[father])
        {
            if(dis[v] == INF)
            {
                dis[v] = dis[father] + 1;
                q.push(v);
                if(dis[v]>maxdist)
                {
                    maxdist = dis[v];
                }
            }
        }
    }
    return maxdist;
}
int maxdis = 1;
vector<int> pson;
void dfs(int u,int deep)
{
    if(!st[u].size())
    {
        if(deep>maxdis)
       {
            maxdis = deep;
            pson.clear();
            pson.push_back(u);
       }else if(deep == maxdis)
       {
            pson.push_back(u);
       }
    }

    for(auto v:st[u])
    {
        dfs(v,deep+1);
    }
}
int main()
{
    int t;//祖宗
    cin>>n;
    for(int i = 1;i<=n;i++)
    {
        int x;
        cin>>x;
        if(x != -1)
        {
            st[x].push_back(i);
        }else {
            t = i;
        }
    }
    //bfs
    //int ret = bfs(t);//从祖宗开始
    //printf("%d\n",ret);
    // bool si = true;//第一个
    // for(int i = 1;i<=n;i++)
    // {
    //     if(dis[i] == ret)
    //     {
    //         if(si)
    //         {
    //             printf("%d",i);
    //             si = false;
    //         } 
    //         else{
    //             printf(" %d",i);
    //         }
    //     }
    // }
   
   //dfs
    dfs(t,1);
    printf("%d\n",maxdis);
    bool ok  = 1;
    for(auto v:pson)
    {
        if(ok)
        {
            ok = 0;
            printf("%d",v);
        }else{
            printf(" %d",v);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以左二子-右兄弟链接表示的,也称为二叉表示法,它是一种常见的的存储方式。在这种存储方式中,每个节点都有一个指向它的第一个子节点的指针(左孩子),以及一个指向它的下一个兄弟节点的指针(右兄弟),叶子节点的左孩子指针为 NULL。 要一棵深度,可以使用深度优先搜索(DFS)或广度优先搜索(BFS算法。这里以 DFS 为例,使用递归实现。 具体实现步骤如下: 1. 如果为空,则深度为 0。 2. 否则,遍历根节点的所有子节点,找到深度最大的子(即子深度最大的子节点),并将其深度加 1,作为根节点的深度。 以下是 Python 实现代码: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def treeDepth(root: TreeNode) -> int: if not root: return 0 max_depth = 0 child = root.left while child: depth = treeDepth(child) max_depth = max(max_depth, depth) child = child.right return max_depth + 1 ``` 其中,TreeNode 表示的节点,包含 val、left、right 三个属性,分别表示节点的值、左孩子和右兄弟。 treeDepth 函数为深度的主函数,输入参数为根节点,返回深度。在函数中,首先判断根节点是否为空,如果为空,则深度为 0。否则,遍历根节点的所有子节点,找到深度最大的子,并将其深度加 1,作为根节点的深度。遍历子节点时,使用 while 循环,每次遍历一个节点,调用 treeDepth 函数出其深度,然后更新 max_depth,最后继续遍历它的右兄弟节点,直到遍历完所有子节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值