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.

A binary search tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

Given any two nodes in a BST, 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 (<= 1000), the number of pairs of nodes to be tested; and N (<= 10000), the number of keys in the BST, respectively. In the second line, N distinct integers are given as the preorder traversal sequence of the BST. 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 BST, 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
6 3 1 2 5 4 8 7
2 5
8 7
1 9
12 -3
0 8
99 99

Sample Output:

LCA of 2 and 5 is 3.
8 is an ancestor of 7.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found. 建树有两种方法,一种是把前序遍历从小到大排序就是中序遍历,然后根据前中序遍历建树。注释部分。
另一种是直接用前序遍历建树。其实中序遍历就是助于判断左右子树,用前序遍历就可以单独判断左右子树的。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
struct tree
{
int Data,Height;
tree *Last,*Left,*Right;
}*head;
int q[],z[],m,n;
map<int,tree *> mp;
tree *createNode(int d,int h)
{
tree *p = new tree();
p -> Data = d;
mp[d] = p;
p -> Height = h;
p -> Last = p -> Left = p -> Right = NULL;
return p;
}
tree *createTree(int ql,int qr,int zl,int zr,int h)
{
tree *p = createNode(q[ql],h);
for(int i = zl;i <= zr;i ++)
{
if(z[i] == q[ql])
{
if(i > zl)p -> Left = createTree(ql + ,ql + i - zl,zl,i - ,h + ),p -> Left -> Last = p;
if(i < zr)p -> Right = createTree(ql + i - zl + ,qr,i + ,zr,h + ),p -> Right -> Last = p;
break;
}
}
return p;
}
tree *createTre(int l,int r,int h)
{
tree *p = createNode(q[l],h);
for(int i = l + ;i <= r + ;i ++)
{
if(i == r + || q[i] >= q[l])
{
if(i > l + )p -> Left = createTre(l + ,i - ,h + ),p -> Left -> Last = p;
if(r >= i)p -> Right = createTre(i,r,h + ),p -> Right -> Last = p;
return p;
}
}
}
void check(int a,int b)
{
if(mp[a] == NULL && mp[b] == NULL)printf("ERROR: %d and %d are not found.\n",a,b);
else if(mp[a] == NULL)printf("ERROR: %d is not found.\n",a);
else if(mp[b] == NULL)printf("ERROR: %d is not found.\n",b);
else
{
tree *t1 = mp[a],*t2 = mp[b];
while(t1 -> Height != t2 -> Height)
{
if(t1 -> Height > t2 -> Height)t1 = t1 -> Last;
else t2 = t2 -> Last;
}
if(t1 == t2)
{
printf("%d is an ancestor of %d.\n",t1 -> Data,a == t1 -> Data ? b : a);
return;
}
t1 = t1 -> Last;
t2 = t2 -> Last;
while(t1 != t2)
{
t1 = t1 -> Last;
t2 = t2 -> Last;
}
printf("LCA of %d and %d is %d.\n",a,b,t1 -> Data);
}
}
int main()
{
int a,b;
scanf("%d%d",&m,&n);
for(int i = ;i < n;i ++)
{
scanf("%d",&q[i]);
//z[i] = q[i];
}
//sort(z,z + n);
// head = createTree(0,n - 1,0,n - 1,0);
head = createTre(,n - ,);
for(int i = ;i < m;i ++)
{
scanf("%d%d",&a,&b);
check(a,b);
}
}

1143. Lowest Common Ancestor (30)的更多相关文章

  1. PAT Advanced 1143 Lowest Common Ancestor (30) [二叉查找树 LCA]

    题目 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both ...

  2. [PAT] 1143 Lowest Common Ancestor(30 分)

    1143 Lowest Common Ancestor(30 分)The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  3. PAT 1143 Lowest Common Ancestor[难][BST性质]

    1143 Lowest Common Ancestor(30 分) The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  4. 1143 Lowest Common Ancestor

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  5. PAT 甲级 1143 Lowest Common Ancestor

    https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312 The lowest common ance ...

  6. PAT 1143 Lowest Common Ancestor

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  7. [PAT] 1143 Lowest Common Ancestor(30 分)1145 Hashing - Average Search Time(25 分)

    1145 Hashing - Average Search Time(25 分)The task of this problem is simple: insert a sequence of dis ...

  8. PAT甲级1143 Lowest Common Ancestor【BST】

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312 题意: 给定一个二叉搜索树,以及他的前 ...

  9. PAT_A1143#Lowest Common Ancestor

    Source: PAT A1143 Lowest Common Ancestor (30 分) Description: The lowest common ancestor (LCA) of two ...

随机推荐

  1. lua元表(简单例子)

    Set = {} Set.mt = {}--定义普通的表作为元表,为了避免命名污染直接放在Set内部 function Set.new(t) local set = {} setmetatable(s ...

  2. 单向HASH——MurmurHash

    //seed 是大质数unsigned long long MurmurHash64B ( const void * key, int len, unsigned int seed ) { const ...

  3. SDOI 2016 Round1 Day1

    储能表 /* 引自zyz大佬的数学思想 */ #include<cstdio> #include<iostream> using namespace std; typedef ...

  4. 实用T-SQL代码

    1.根据出生日期计算当前已满周岁 DECLARE @birth datetime SET @birth='1990-01-01' ),) ),) 2.COUNT(expression) just re ...

  5. [转]linux terminal中使用proxy

    转自:http://www.cnblogs.com/JoJosBizarreAdventure/p/5892383.html 在linux terminal中使用代理 方法一: terminal中输入 ...

  6. mysql存储过程之事务篇

    mysql存储过程之事务篇 事务的四大特征: ACID:Atomic(原子性).Consistent(一致性).Isolated(独立性).Durable (持久性) MySQL的事务支持不是绑定在M ...

  7. 关于logback

    1 logback是一个日志框架 2 logback的构成 LogBack被分为3个组件,logback-core, logback-classic 和 logback-access. 其中logba ...

  8. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  9. PAT 1057. 数零壹(20)

    给定一串长度不超过105的字符串,本题要求你将其中所有英文字母的序号(字母a-z对应序号1-26,不分大小写)相加,得到整数N,然后再分析一下N的二进制表示中有多少0.多少1.例如给定字符串“PAT ...

  10. Linux c编程:I/O多路复用之select

    一般我们在写socet程序的时候调用的accept,recv等操作都是阻塞型的.意思就是如果我们一直收不到数据那么则会被阻塞.所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待 ...