当前位置:首页 > GESP > 2023年【GESP六级真题解析】工作沟通题目(LCA算法+Tarjan模板):代码详解与优化思路

2023年【GESP六级真题解析】工作沟通题目(LCA算法+Tarjan模板):代码详解与优化思路

6个月前 (09-02)

2023年【GESP六级真题解析】工作沟通题目(LCA算法+Tarjan模板):代码详解与优化思路 GESP六级 LCA算法 Tarjan算法 洛谷 C++ 第1张

一、题目解读

2023年GESP六级“工作沟通”题目(洛谷P10109)要求处理公司层级关系,通过给定员工与直属领导的映射,实现多组查询:找出多个员工节点的共同上级(即最近公共祖先,LCA)。题目重点考察树结构处理、LCA算法设计与优化,需平衡时间与空间复杂度。

二、解题思路

采用离线处理+Tarjan算法框架,核心为:

1. 预处理阶段:构建结构,存储每个节点的父节点及深度;利用倍增法预处理2^k级祖先,降低LCA查询复杂度。

2. 深度优先搜索DFS):计算节点深度并构建父子关系树。

3. LCA查询优化:通过深度调整与倍增跳跃,快速定位最近公共祖先。

4. Tarjan算法:离线处理多组查询,避免重复计算,提升效率。

三、解题步骤

1. 输入与初始化:读取N个节点及父子关系,构建树结构。

2. 预处理:

    初始化父节点数组:parent[i]存储i的直属领导。

    倍增预处理:计算up[i][k](i的2^k级祖先)。

    深度优先搜索:递归计算每个节点深度。

3. 查询处理:

    对每组m个员工,通过LCA算法找到共同上级:

        深度对齐:将深度较深的节点提升到与最浅节点同一层。

        倍增跳跃:同步向上查找,直至找到最近公共祖先。

4. 输出结果:返回每组查询的LCA节点编号。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXN = 1e5 + 5;
const int LOG = 20;

vector<int> parent(MAXN);
vector<vector<int>> up(MAXN, vector<int>(LOG));
vector<int> depth(MAXN);

// 预处理每个节点的2^k级祖先
void preprocess(int n) {
    up[0][0] = 0; // 老板的父节点是自己
    for(int i = 1; i < n; ++i) {
        up[i][0] = parent[i];
    }
    
    for(int k = 1; k < LOG; ++k) {
        for(int i = 0; i < n; ++i) {
            up[i][k] = up[up[i][k-1]][k-1];
        }
    }
}

// 计算节点u的深度
void dfs(int u, int p, const vector<vector<int>>& children) {
    for(int v : children[u]) {
        if(v != p) {
            depth[v] = depth[u] + 1;
            dfs(v, u, children);
        }
    }
}

// 提升节点u到指定深度
int lift(int u, int target_depth) {
    for(int k = LOG-1; k >= 0; --k) {
        if(depth[u] - (1 << k) >= target_depth) {
            u = up[u][k];
        }
    }
    return u;
}

// 查找两个节点的LCA
int lca(int u, int v) {
    if(depth[u] < depth[v]) swap(u, v);
    u = lift(u, depth[v]);
    
    if(u == v) return u;
    
    for(int k = LOG-1; k >= 0; --k) {
        if(up[u][k] != up[v][k]) {
            u = up[u][k];
            v = up[v][k];
        }
    }
    return parent[u];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N;
    cin >> N;
    
    vector<vector<int>> children(N);
    parent[0] = 0;
    for(int i = 1; i < N; ++i) {
        cin >> parent[i];
        children[parent[i]].push_back(i);
    }
    
    // 预处理
    preprocess(N);
    depth[0] = 0;
    dfs(0, -1, children);
    
    int Q;
    cin >> Q;
    while(Q--) {
        int m;
        cin >> m;
        vector<int> group(m);
        for(int i = 0; i < m; ++i) {
            cin >> group[i];
        }
        
        // 找到所有节点的LCA
        int current_lca = group[0];
        for(int i = 1; i < m; ++i) {
            current_lca = lca(current_lca, group[i]);
            if(current_lca == 0) break; // 已经到根节点
        }
        
        cout << current_lca << '\n';
    }
    
    return 0;
}

五、总结

本文代码通过倍增LCA算法与Tarjan框架,高效解决了工作沟通中的层级查询问题。关键点在于:

1. 预处理阶段降低单次查询时间复杂度至O(logN)。

2. 深度调整与同步跳跃优化LCA查找过程。

3. Tarjan离线处理减少重复计算,适用于多组查询场景。

该解法兼顾效率与代码可读性,为树结构LCA问题的典型模板。

参考:2023年GESP六级工作沟通题解

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣第92题:三步定位 精准反转链表指定区间

力扣第92题:三步定位 精准反转链表指定区间

题目解读给定一个单链表和两个整数left与right,要求将链表中从第left个节点到第right个节点的部分进行反转,而保持其他部分不变。例如,对于链表1→2→3→4→5,left=2,right=...

2024年GESP四级宝箱题(洛谷P4006)题解:滑动窗口算法优化最长子序列和

2024年GESP四级宝箱题(洛谷P4006)题解:滑动窗口算法优化最长子序列和

一、题目解读本题为2024年GESP四级中的“宝箱”问题(对应洛谷P4006),要求在一个由n个宝箱组成的序列中,找出一个连续子序列,使得该子序列中宝箱价值之和最大,且子序列中最大值与最小值的差不超过...

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

一、题目解读洛谷1184题要求处理一组地点列表与行程记录,统计其中匹配的天数。题目难点在于高效处理带有空格的字符串输入,以及快速判断每日行程是否在高手可去地点集合中。需要兼顾输入格式解析与算法效率。二...

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。