1 条题解

  • 0
    @ 2026-2-17 17:30:50
    #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
    上传者