3555. 二叉树(北京邮电大学考研机试题)

3555. 二叉树

⭐️难度:简单(其实困难)

⭐️类型:树

📖题目:题目链接

输入样例:

1

8 4

2 3

4 5

6 -1

-1 -1

-1 7

-1 -1

8 -1

-1 -1

1 6

4 6

4 5

8 1

输出样例:

2

4

2

4

🌟思路:

先试着把样例中的树画出来:

再思考怎么找两个结点的最小距离。

第一种情况:2和8的距离,2已经在8的路径上了,很容易算得2到8的距离;

第二种情况:4和8的距离,4和8不在同一条路径上,此时需要找4和8路径共同的交点 ,也就是2,再计算4到2的距离+8到2的距离

步骤:

1️⃣先构造树

2️⃣找到结点到根的路径

3️⃣找交点

4️⃣总结规律

笔记:

📚题解:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<vector>  // vector不需要.h
#include<list>
#include<set>  // // 可以用 set 和 multiset
#include<unordered_set> // 可以用 unordered_set 和 unordered_multiset
#include<map>  // 可以用 map 和 multimap
#include<unordered_map> // 可以用 unordered_map 和 unordered_multimap
#include<algorithm>
#include<string>
#include<iostream>
#include<queue>
#include<stack>

using namespace std;


struct TreeNode {
    int num;
    TreeNode* left; 
    TreeNode* right;
    TreeNode* parent;  // 因为要沿上找路径,定义parent会更方便
};

int main() {
 
    int t;
    scanf("%d", &t);
    for (int i = 0;i < t;i++) {
        int n, m;
        scanf("%d%d", &n, &m);

        vector<TreeNode*> nodearr(n + 1);  // 定义n+1空间,方便与结点编号对应
        for (int j = 1;j <= n;j++) {
            nodearr[j] = new TreeNode;
            nodearr[j]->num = j;
        }

        nodearr[1]->parent = NULL;

        // 构建树
        for (int j = 1;j <= n;j++) {  // 输入n组数据
            int left,right;
            scanf("%d%d", &left, &right);
            if (left != -1) {
                nodearr[j]->left = nodearr[left];   // 第i行输入表示第i个结点左右孩子的情况
                nodearr[left]->parent = nodearr[j];
            }
            else {
                nodearr[j]->left = NULL;
            }
            if (right != -1) {
                nodearr[j]->right = nodearr[right];
                nodearr[right]->parent = nodearr[j];
            }
            else {
                nodearr[j]->right = NULL;
            }
        }

        int lhs, rhs;
        for (int j = 0;j < m;j++) {  // 输入m组待测数据
            scanf("%d%d", &lhs, &rhs);
            vector<int> lvec;  // 存所给第一个结点的路径
            TreeNode* p = nodearr[lhs];
            while (p != NULL) {
                lvec.push_back(p->num);
                p = p->parent;
            }
            vector<int> rvec;  // 存所给第二个结点的路径
            p = nodearr[rhs];
            while (p != NULL) {
                rvec.push_back(p->num);
                p = p->parent;
            }

            // 找交点
            int l = lvec.size() - 1;
            int r = rvec.size() - 1;
            while (true) {
                if (l < 0 || r < 0|| (lvec[l] != rvec[r])) {  // 没有找到公共点 或 左结点和右节点到公共交点前一个结点
                    break;
                }
                l--;
                r--;
            }
            printf("%d\n", l + r + 2);
        }

    }

    

    return 0;
}
相关推荐
如君愿11 小时前
考研复习 Day 39 | 密码学--第四章 分组密码(上)
考研·密码学
daanpdf2 天前
考研英语一历年真题及答案解析PDF(2010-2026)百度网盘
考研·pdf
05候补工程师2 天前
【408狂飙·数据结构】核心考点深度复盘:数组地址计算、特殊矩阵压缩存储与树的五大性质解题直觉
数据结构·笔记·线性代数·考研·算法·矩阵
daanpdf2 天前
历年考研数学一、数学二、数学三真题试卷及答案PDF
考研·pdf
如君愿2 天前
考研复习 Day 38 | 密码学--第三章 古典密码
考研·密码学·课后习题
蒟蒻的贤3 天前
编译原理里的冲突到底是什么?
考研·算法
荒原之梦网3 天前
在不确定的命题环境中,如何建立稳定的考研数学备考体系
考研·考研数学·荒原之梦考研数学
05候补工程师3 天前
【线性代数】硬核复习笔记:核心定理推导、矩阵变换本质与自创高频题解
经验分享·笔记·线性代数·考研·矩阵
如君愿3 天前
考研复习 Day 37 | 密码学--第一章 绪论、第二章 相关的基础知识
考研·密码学
别或许3 天前
12、高数----一元函数积分学的应用(3)物理应用与经济应用
考研