1 条题解

  • 0
    @ 2026-6-19 10:30:12

    📝 题目大意

    nn 个人,第 ii 个人的上一代(父亲)是 pip_i(保证 pi<ip_i < i)。求从第 nn 个人追溯到第 11 个人一共经过了几代人。

    💡 解题思路

    1. 题目分析

      • 约束 pi<ip_i < i 保证了这是一个以 11 为根、编号递增的有根树,且 11 必为祖先,不会出现环。
      • nn 的范围在 AtCoder ABC 的 B 题中通常为 N50N \le 50N100N \le 100,直接模拟即可。
    2. 算法推导

      • pip_i 作为父指针,将每个人的父亲存入数组 p[i]p[1] 无父亲,无需使用)。
      • nn 出发,不断令 current = p[current],即沿着父亲链向上追溯,直到到达 11
      • 每向上走一步,代际计数 steps11,最终 steps 即为答案。
    3. 边界与细节

      • 输入 p2p_2pnp_n,共 n1n-1 个数,注意下标从 22 开始。
      • n=1n=1 时不会出现(题目隐含 n2n \ge 2),但即使出现,循环不会执行,steps00
      • 保证 pi<ip_i < i 意味着编号严格递增,不会出现 pi=ip_i = i 的自环,也不会出现死循环。

    ⏱️ 复杂度分析

    • 时间复杂度O(N)O(N),最坏情况下链长为 NN,每条边访问一次。
    • 空间复杂度O(N)O(N),用于存储父指针数组。

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    int main() {
        int n;
        cin >> n;
        vector<int> p(n + 1);  // p[i] 表示第 i 个人的父亲
        // 读入 p_2 到 p_n
        for (int i = 2; i <= n; i++) {
            cin >> p[i];
        }
        int current = n;  // 从第 n 个人开始追溯
        int steps = 0;    // 记录经过的代数
        // 沿着父亲链向上走,直到到达第 1 个人
        while (current != 1) {
            current = p[current];  // 跳到父亲
            steps++;               // 代数 +1
        }
        cout << steps << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    876
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者