描述
前面我们学习过了树这种特殊的数据结构。我们知道除了根结点,树上的每个都有父结点。这里我们提到另外一个概念,祖先 结点。所谓祖先结点,就是父结点的父结点,父结点的父结点的父结点......,所有沿着父亲结点向根结点走的结点都能称为祖先结点。特殊的是,自己也可以称为自己的祖先结点。
两个结点的最近公共祖先结点就是这两个结点沿着父节结点一直到根结点的路径上第一个相遇的结点。给出一棵树,求出树上的两个结点的最近公共祖先。
输入输出格式
输入
输入第一行一个整数 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 }