YCOJ 2061103【最近公共祖先】

博客围绕求解树上两个结点的最近公共祖先展开。先介绍了祖先结点和最近公共祖先结点的概念,接着给出输入输出格式,包含树的结点数、各结点父节点信息及要查询的两个结点编号等,还提及解题思路可用set,最后给出题解的转载链接。

描述

  前面我们学习过了树这种特殊的数据结构。我们知道除了根结点,树上的每个都有父结点。这里我们提到另外一个概念,祖先 结点。所谓祖先结点,就是父结点的父结点,父结点的父结点的父结点......,所有沿着父亲结点向根结点走的结点都能称为祖先结点。特殊的是,自己也可以称为自己的祖先结点。

  两个结点的最近公共祖先结点就是这两个结点沿着父节结点一直到根结点的路径上第一个相遇的结点。给出一棵树,求出树上的两个结点的最近公共祖先。

输入输出格式

输入

  输入第一行一个整数 n(1 ≤ n ≤ 1000) 表示树的结点数,结点的编号为 1 到 n。

  接下来一行,输入 n 个用空格隔开的整数,第 i 个整数表示结点 i 的父亲节点。如果是 -1 表示该结点为根节点。

  接下来一行输入两个整数 u, v(1 ≤ u, v ≤ n)。

输出

  输出结点 u 和 v 的最近公共祖先结点的编号。

输入输出样例

输入样例1

5
-1 1 2 2 1
5 4

输出样例1

1

输入样例2

7
4 6 1 7 2 7 -1
6 5

输出样例2

6

解题思路

  这道题提到了一个祖先节点,并且自己也可以称为自己的祖先结点,我们可以把它画成一棵树。这道题用set在合适不过了,我们开一个a数组,利用循环向set里插入i元素,在对它进行查找,找出最近公共祖先结点的编号,就可以完成本题了。然而我并没有用

题解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int a[1010];
 5 int a11[1010],a22[1010];
 6 int main()
 7 {
 8     int ans=0;
 9     cin>>n;
10     for(int i=1;i<=n;i++)
11     {
12         int x;
13         cin>>x;
14         a[i]=x; 
15     }
16     int a1,a2;
17     cin>>a1>>a2;
18     int sum;
19     sum=a1;
20     while(sum!=-1)
21     {
22         ans++;
23         a11[ans]=sum;
24         sum=a[sum];
25     }
26     sum=a[a2];
27     int aaa=ans;
28     ans=0;
29     while(sum!=-1)
30     {
31         ans++;
32         a22[ans]=sum;
33         sum=a[sum];
34     }
35     for(int i=1;i<=aaa;i++)
36     {
37         for(int j=1;j<=ans;j++)
38         {
39             if(a11[i]==a22[j])
40             {
41                 cout<<a11[i];
42                 return 0;
43             }
44         }
45     }
46     return 0;
47 }

 

转载于:https://www.cnblogs.com/hualian/p/11159829.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值