首页 > 其他分享 >洛谷题单指南-二叉树-P3884 [JLOI2009] 二叉树问题

洛谷题单指南-二叉树-P3884 [JLOI2009] 二叉树问题

时间:2024-03-18 15:02:43浏览次数:25  
标签:int 洛谷题 tree JLOI2009 depth 二叉树 深度 节点

原题链接:https://www.luogu.com.cn/problem/P3884

题意解读:要计算二叉树的深度、宽度、节点间的距离,深度、宽度的概念很好理解,节点间的距离描述是:节点u,v 之间的距离表示从u 到v的最短有向路径上向根节点的边数的两倍加上向叶节点的边数。说人话就是:u到v的距离=uv最近公共祖先到u的距离 * 2 + uv最近公共祖先到v的距离。

解题思路:

对于深度来说,P4913已经做过介绍,DFS可以解决;

对于宽度来说,只需要在DFS计算深度的过程中,记录每一个深度一共有多少个节点,最后取某个深度最多的节点数量即是宽度;

对于距离来说,如x到y的距离,需要先求x、y的最近公共祖先f,然后计算x到f的距离* 2 + y到f的距离 即可。

求x、y的最近公共祖先,可以通过向上标记法,遍历x的所有祖先(包括x自己),用数组fathers[]标记,再遍历y的所有祖先,第一个在fathers中标记过的即最近公共祖先。

由于要搜索祖先,二叉树节点需要存储父、子节点。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 105;

struct node
{
    int father, left, right;
} tree[N];

int n, u, v, x, y;
int maxdepth; //树的深度
int depthcnt[N]; //每种深度的节点数
int depthall[N]; //每个节点的深度

bool fathers[N]; //x的所有祖先标记

void dfs(int root, int depth)
{
    if(root == 0) return;
    maxdepth = max(maxdepth, depth); //更新树的深度
    depthcnt[depth]++; //深度depth的节点数++
    depthall[root] = depth;
    
    dfs(tree[root].left, depth + 1);
    dfs(tree[root].right, depth + 1);
}

int lca(int x, int y)
{
    int ans; 
    int tmpx = x, tmpy = y;
    while(tmpx)
    {
        fathers[tmpx] = true;
        tmpx = tree[tmpx].father;
    }
    while(tmpy)
    {
        if(fathers[tmpy]) 
        {
            ans = tmpy;
            break;
        }
        tmpy = tree[tmpy].father;
    }
    return ans;
}

int main()
{
    cin >> n;
    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        if(tree[u].left == 0) tree[u].left = v;
        else tree[u].right = v;
        tree[v].father = u;
    }
    cin >> x >> y;
    dfs(1, 1);

    int width = 0; //树的宽度是深度最多的节点数
    for(int i = 1; i <= n; i++) width = max(width, depthcnt[i]);

    int f = lca(x, y);
    //x到y的距离=xy最近公共祖先到x的距离 * 2 + xy最近公共祖先到y的距离
    int distance = (depthall[x] - depthall[f]) * 2 + depthall[y] - depthall[f];

    cout << maxdepth << '\n' << width << '\n' << distance << endl;;
}

 

标签:int,洛谷题,tree,JLOI2009,depth,二叉树,深度,节点
From: https://www.cnblogs.com/jcwy/p/18080411

相关文章

  • 二叉树的广度优先遍历(力扣102)
    文章目录题目前知BFS是什么?队列的基本操作有什么?题解一、思路二、解题方法三、Code总结题目Problem:102.二叉树的层序遍历给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。前知BFS是什么?树的广度优先遍历(BFS)是一种遍......
  • 树与二叉树(数据结构)
    本篇博客讲解树与二叉树,后续会继续讲解堆——————————————————————1.树概念及结构1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的......
  • Leecode 二叉树的前序遍历
    Day2刷题我的思路:用数组list存储遍历结果,利用ArrayList的方法实现嵌套!importjava.util.*;classSolution{//defininganarraylistpublicList<Integer>preorderTraversal(TreeNoderoot){List<Integer>Traversal=newArrayList<>();......
  • 【算法与数据结构】堆排序&&TOP-K问题之深入解析二叉树(三)
    文章目录......
  • 数据结构笔记(十四)二叉树的遍历(递归)
    四种访问方式:前序遍历,中序遍历,后序遍历,层序遍历这篇文章主要为前序,中序,后序遍历的递归形式,递归形式较为简单,后面更新遍历的循环形式较为复杂,建议使用递归形式#include<stdio.h>#include<stdlib.h>typedefcharE;typedefstructTreeNode*Node;structTreeNod......
  • 面试中可能问到的几种树结构(二叉树,平衡二叉树,红黑树,B树和B+树)
    二叉树的概念二叉树是一种树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。平衡二叉树概念平衡二叉树,是二叉树的一种变形,左子树的深度和右子树的深度不能超过一。红黑树概念红黑树是一种自......
  • leedcode-翻转二叉树
    自己写的:classSolution:definvertTree(self,root:Optional[TreeNode])->Optional[TreeNode]:#创建一个新的TreeNode以存储反转后的树newroot=TreeNode()#如果输入的根节点为空,则返回空ifnotroot:......
  • 二叉树的迭代遍历
    二叉树前后序遍历(迭代)#include<bits/stdc++.h>usingnamespacestd;structNode{intdata;Node*left;Node*right;Node(intvalue=0):data(value),left(nullptr),right(nullptr){}};Node*insertEle();voidpreorder(Node*pNode);voidmid......
  • 代码随想录 第21天 | ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ●
    leetcode:530.二叉搜索树的最小绝对差-力扣(LeetCode)思路:判断最小绝对差,肯定用中序遍历,双指针一前一后依次判断。classSolution{intresult=Integer.MAX_VALUE;TreeNodepre=null;publicintgetMinimumDifference(TreeNoderoot){if(root==......
  • 【leetcode】二叉树的前序遍历➕中序遍历➕后序遍历
    大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞......