📌  相关文章
📜  教资会网络 | UGC NET CS 2015 年 6 月 – III |问题 38(1)

📅  最后修改于: 2023-12-03 15:10:14.940000             🧑  作者: Mango

教资会网络 | UGC NET CS 2015 年 6 月 – III |问题 38
简介

教资会网络 (UGC NET) 是印度国家资格考试,主要针对大学与学院的教学岗位。

问题38是关于计算机科学的一道题目,主要考察程序员在数据结构方面的知识。

题目描述

给定一个树 T 和一个节点 v,定义 T 的子树的深度为包含 v 的子树的最大深度。使用 DFS (深度优先搜索)算法实现一个函数,计算树 T 中以节点 v 为根节点的子树的深度。

输入格式

输入包括三行: 第一行是一个整数 n,表示树 T 的节点个数, 第二行是 n 个整数,表示树 T 的节点编号, 第三行包含 n - 1 个用空格分隔的整数 a_2, a_3,… , a_n,表示编号从 2 到 n 的节点的父节点编号。

输出格式

输出一个整数,表示以节点 v 为根节点的子树的深度。

样例输入
6
1 2 3 4 5 6
1 1 2 2 3 3
4
样例输出
3
解题思路

深度优先搜索是实现该问题的最佳算法,因为我们需要遍历整个树,找到与 v 相关的子树。

1、首先建立一个 adjacency list,用于存储树 T 的边。

        // 树的数据结构定义
        struct Node
        {
            int val;
            vector<Node *> children;
        };
 
        // 建立邻接表,用于存储树 T 的边
        vector<vector<int>> adjacencyList(n + 1);
        for (int i = 2; i <= n; i++)
        {
            int parent;
            cin >> parent;
            adjacencyList[parent].push_back(i);
        }

2、使用深度优先搜索函数计算以节点 v 为根节点的子树的深度。在递归搜索时,我们需要计算子树的最大深度。在搜索结束后返回该值。

        // DFS 搜索以节点 v 为根节点的子树
        int dfs(Node *root)
        {
            if (!root)
            {
                return 0;
            }
            int maxHeight = 0;
            for (Node *child : root->children)
            {
                maxHeight = max(maxHeight, dfs(child));
            }
            return maxHeight + 1;
        }
 
        // 查找以节点 v 为根节点的子树
        int findSubtreeDepth(Node *root, int v)
        {
            if (root->val == v)
            {
                return dfs(root);
            }
            int subtreeDepth = 0;
            for (Node *child : root->children)
            {
                subtreeDepth = max(subtreeDepth, findSubtreeDepth(child, v));
            }
            return subtreeDepth;
        }
完整代码
#include <bits/stdc++.h>
 
using namespace std;
 
struct Node
{
    int val;
    vector<Node *> children;
};
 
int main()
{
    int n;
    cin >> n;
 
    vector<int> nodeValues(n + 1);
    vector<vector<int>> adjacencyList(n + 1);
 
    // 读入节点编号
    for (int i = 1; i <= n; i++)
    {
        cin >> nodeValues[i];
    }
 
    // 建立邻接表,用于存储树 T 的边
    for (int i = 2; i <= n; i++)
    {
        int parent;
        cin >> parent;
        adjacencyList[parent].push_back(i);
    }
 
    // 构建树结构
    map<int, Node *> nodes;
    for (int i = 1; i <= n; i++)
    {
        int val = nodeValues[i];
        if (!nodes.count(i))
        {
            nodes[i] = new Node({val, {}});
        }
        for (int child : adjacencyList[i])
        {
            if (!nodes.count(child))
            {
                nodes[child] = new Node({nodeValues[child], {}});
            }
            nodes[i]->children.push_back(nodes[child]);
        }
    }
 
    int v;
    cin >> v;
 
    // DFS 搜索以节点 v 为根节点的子树
    int dfs(Node *root)
    {
        if (!root)
        {
            return 0;
        }
        int maxHeight = 0;
        for (Node *child : root->children)
        {
            maxHeight = max(maxHeight, dfs(child));
        }
        return maxHeight + 1;
    }
 
    // 查找以节点 v 为根节点的子树
    int findSubtreeDepth(Node *root, int v)
    {
        if (root->val == v)
        {
            return dfs(root);
        }
        int subtreeDepth = 0;
        for (Node *child : root->children)
        {
            subtreeDepth = max(subtreeDepth, findSubtreeDepth(child, v));
        }
        return subtreeDepth;
    }
 
    int subtreeDepth = findSubtreeDepth(nodes[1], v);
    cout << subtreeDepth << endl;
 
    return 0;
}