📌  相关文章
📜  国际空间研究组织 | ISRO CS 2014 |问题 36(1)

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

ISRO CS 2014 | 问题 36

这道题是一道有关树的问题,需要求出根节点到所有其他节点的路径之和,具体来说,就是对于每个节点,求它到根节点的距离,再将所有距离相加。

输入格式

输入共两行,第一行为一个整数n,表示树的节点数,节点编号为1到n。

第二行有n-1个整数,表示节点的父亲节点,其中第i个数表示节点i+1的父亲节点编号。

输出格式

输出一个整数,表示根节点到所有其他节点的路径之和。

示例

输入:

5
1 2 2 3 3

输出:

8
解释

该树的结构如下所示:

    1
   / \
  2   2
 / \ / \
3   4 4  3

对于节点1,距离为0;对于节点2、3、4,距离为1;对于节点5,距离为2。所以路径和为 0 + 1 + 1 + 1 + 2 = 5。

思路

由于题目给出的父亲节点是从1到n-1的,而我们通常处理的是从0到n-1的节点编号,因此在输入时需要将所有的父亲节点编号减1。

当得到每个节点到根节点的距离后,将距离相加即可。

因为输入的树是一棵普通树(非二叉树),因此需要用一些数据结构来存储和处理树的信息。这里采用一个vector数组来存储每个节点的子节点,以及int数组dist来存储每个节点到根节点的距离。

核心代码如下:

vector<int> tree[N]; // 存储树的信息
int dist[N]; // 存储每个节点到根节点的距离

void dfs(int u, int p, int d) {
    dist[u] = d;
    for (auto v : tree[u]) {
        if (v != p) dfs(v, u, d + 1);
    }
}

int main() {
    int n;
    scanf("%d", &n);

    // 构建树:读入父节点,将当前节点作为父节点的子节点
    for (int i = 1; i < n; i++) {
        int p;
        scanf("%d", &p);
        tree[p-1].push_back(i);
    }

    dfs(0, -1, 0); // 从根节点开始递归

    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans += dist[i]; // 将每个节点到根节点的距离相加
    }
    printf("%d\n", ans);

    return 0;
}
完整代码
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

vector<int> tree[N]; // 存储树的信息
int dist[N]; // 存储每个节点到根节点的距离

void dfs(int u, int p, int d) {
    dist[u] = d;
    for (auto v : tree[u]) {
        if (v != p) dfs(v, u, d + 1);
    }
}

int main() {
    int n;
    scanf("%d", &n);

    // 构建树:读入父节点,将当前节点作为父节点的子节点
    for (int i = 1; i < n; i++) {
        int p;
        scanf("%d", &p);
        tree[p-1].push_back(i);
    }

    dfs(0, -1, 0); // 从根节点开始递归

    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans += dist[i]; // 将每个节点到根节点的距离相加
    }
    printf("%d\n", ans);

    return 0;
}