The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.
Given any two nodes in a binary tree, you are supposed to find their LCA.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.
Output Specification:
For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found..
Sample Input:
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99
Sample Output:
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
这题写了1小时14分钟。。。
根据前序中序递归建树。用set判断点是否存在。如果都在。分别求出两个点从根到他们的各自路径。从较长的路径中查找2个点是否都在。都在则输出 X is an ancestor of Y. 否则逐个比较路径,分叉口就是LCA。比如2的路径(5372),6的路径(536),那么分叉口就是3,LCA就是3.
又看了下其他大佬的思路,简直吊打我
#include<stdio.h>
#include<vector>
#include<set>
#include<stdlib.h>
using namespace std;
int pre[10010],in[10010];
set<int>s;
vector<int>path1,path2,path,tmp;
typedef struct Node* node;
struct Node{
int x;
node left;
node right;
};
node build(int s1,int e1,int s2,int e2){
node T=(node)malloc(sizeof(struct Node));
T->x=pre[s1];
T->left=T->right=0;//NULL
int root,i;
for(i=s2;i<=e2;i++){
if(in[i]==pre[s1]){
root=i;break;
}
}
if(root!=s2){
T->left=build(s1+1,root-s2+s1,s2,root-1);
}
if(root!=e2){
T->right=build(root-s2+s1+1,e1,root+1,e2);
}
return T;
}
void dfs(node T,int c){
if(T){
tmp.push_back(T->x);
if(T->x==c){
path=tmp;
tmp.pop_back();//不要忘了!!!
return;//不return 最后2点超时
}
dfs(T->left,c);
dfs(T->right,c);
tmp.pop_back();
}
}
int main(){
int n,m,i,c1,c2,index1,index2;
scanf("%d %d",&m,&n);
for(i=0;i<n;i++){
scanf("%d",&in[i]);//中序
s.insert(in[i]);//集合便于后面查找是否存在
}
for(i=0;i<n;i++){
scanf("%d",&pre[i]);//前序
}
node T=build(0,n-1,0,n-1);//建树
while(m--){
scanf("%d %d",&c1,&c2);
if(s.find(c1)==s.end()&&s.find(c2)==s.end()){//都不在
printf("ERROR: %d and %d are not found.\n",c1,c2);
}
else if(s.find(c1)==s.end()){//有一个不在
printf("ERROR: %d is not found.\n",c1);
}
else if(s.find(c2)==s.end()){//有一个不在
printf("ERROR: %d is not found.\n",c2);
}
else{
tmp.clear();//74行用了tmp,所以下次dfs前clear
dfs(T,c1);
path1=path;//保存c1路径
dfs(T,c2);
path2=path;//保存c2路径
tmp=path1.size()>path2.size()?path1:path2;
index1=index2=-1;
for(i=0;i<tmp.size();i++){
if(tmp[i]==c1){
index1=i;
}
if(tmp[i]==c2){
index2=i;
}
}
if(index1!=-1&&index2!=-1){//两个点都在同一路径
if(index1>index2){
swap(c1,c2);//不用#include<algorithm>??
}
printf("%d is an ancestor of %d.\n",c1,c2);
}
else{//逐个比较,不同的分叉点就是LCA
for(i=0;i<path1.size()-1&&i<path2.size()-1;i++){
if(path1[i]==path2[i]&&path1[i+1]!=path2[i+1]){
printf("LCA of %d and %d is %d.\n",c1,c2,path1[i]);
break;
}
}
}
}
}
}
705




被折叠的 条评论
为什么被折叠?



