1 条题解
-
0
#include<bits/stdc++.h> using namespace std; // [1] n:树的结点总数;a、b:需要求解最近公共祖先的两个目标结点 int n , a , b; // [2] 邻接表数组,存储树的无向边,arr[x]保存与结点x直接相连的所有结点 vector<int> arr[100100]; // [3] 父节点数组,fa[x]存储结点x的父节点编号 int fa[100100]; // [4] 深度数组,dep[x]存储结点x在树中的深度 int dep[100100]; // [10] 深度优先搜索:遍历整棵树,预处理每个结点的父节点和深度 // 参数x:当前访问结点;参数y:当前结点的父结点;参数len:当前结点的深度 void dfs(int x , int y ,int len) { dep[x] = len ; // [11] 记录当前结点深度 fa[x] = y; // [12] 记录当前结点父节点 // [13] 遍历当前结点的所有相邻结点 for(int i = 0 ; i < arr[x].size() ; i++) { // [14] 若相邻结点是父结点,跳过以避免死循环 if(arr[x][i] == y) continue; // [15] 递归访问子结点 dfs(arr[x][i] , x , len +1); } } // [17] 求解两个结点的最近公共祖先,返回LCA的结点编号 // 参数x、y:需要求解LCA的两个目标结点 int lca(int x , int y) { // [18] 第一步:将深度更深的结点向上跳,直到两结点深度相同 while(dep[x] < dep[y]) { y = fa[y]; } while(dep[x] > dep[y]) { x = fa[x]; } // [19] 第二步:两结点同时向上跳,直到相遇 while(x != y) { y = fa[y]; x = fa[x]; } // [20] 返回相遇的结点(即最近公共祖先) return x; } int main() { // [5] 读入总结点数和两个目标结点 cin >> n >> a >> b; // [6] 构建树的无向邻接表 for(int i = 1 ; i <= n - 1 ; i++) { int x , y; cin >> x >> y; arr[x].push_back( y ); arr[y].push_back( x ); } // [7] 冗余初始化,可删除 for(int i = 1 ; i <= n ; i++) fa[i] = i; // [8] 从根结点1启动DFS预处理 dfs(1 , 1 , 1); // [16] 调用LCA函数并输出结果 cout<< lca(a , b); return 0; }
- 1
信息
- ID
- 1078
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者