PAT A1151 LCA in a Binary Tree
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:同A 1143!
通过先序和中序找根,然后判断根是否是LCA:
1- 如果u、v都在根的左边:递归的去左子树找
2- 都在右边:递归去右子树找
3- 其他情况有:
-3-1:一边一个,此时的根就是u、v的LCA
-3-2:一个是根:这个是另一个的LCA -
TIPS :通过结点在中序序列的下标,就可以判断u、v是在根的做还是右->所以输入时应用一数组记录ino[]中结点对应的下标
-
code 1:
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
const int maxn = 10100; //!!!Wrong 1:结点数是10000,不是1000
int n, m, q1, q2, que1, que2;
//int ino[maxn], preo[maxn]; //最好用vector,再resize设置大小,防止maxn写错
vector<int> ino, preo;
unordered_map<int, int> mark, pos;
void findRoot(int preL, int inL, int inR){
if(inL > inR) return;
int inRoot = pos[preo[preL]];
int numL = inRoot - inL;
if(que1 < inRoot && que2 < inRoot) //1- 都在左边
findRoot(preL+1, inL, inRoot-1);
else if(que1 > inRoot && que2 > inRoot) //2- 都在右边
findRoot(preL+numL+1, inRoot+1, inR);
else{ //3-
if(que1 == inRoot || que2 == inRoot) //3-1 一个是根
printf("%d is an ancestor of %d.\n", que1 == inRoot? q1 : q2, que1 == inRoot? q2 : q1);
else //3-2 一左一右:当前r为LCA
printf("LCA of %d and %d is %d.\n", q1, q2, ino[inRoot]);
return;
}
}
int main(){
scanf("%d %d", &m, &n);
ino.resize(n+1); preo.resize(n+1);
for(int i = 0; i < n; ++i){
scanf("%d", &ino[i]);
pos[ino[i]] = i;
}
for(int i = 0; i < n; ++i){
scanf("%d", &preo[i]);
mark[preo[i]] = 1;
}
for(int i = 0; i < m; ++i){
scanf("%d %d", &q1, &q2);
que1 = pos[q1], que2 = pos[q2];
if(mark[q1] * mark[q2] == 1) findRoot(0, 0, n-1);
else if(mark[q1] == mark[q2]) printf("ERROR: %d and %d are not found.\n", q1, q2); //都不是节点
else printf("ERROR: %d is not found.\n", mark[q1] == 0 ? q1 : q2);
}
return 0;
}
- T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int in[maxn], pre[maxn];
unordered_map<int, int> pos;
bool flg;
void Create(int preL, int preR, int inL, int inR, int q1, int q2){
if(preL > preR) return;
int r = pre[preL], pos_r = pos[r]; //Wrong 1:样例4必超时 :用记录r在中序序列中的位置,来代替每次遍历
int numL = pos_r - inL;
if(flg){
if(r == q1 || r == q2){
printf("%d is an ancestor of %d.\n", r, r == q1 ? q2 : q1);
flg = false;
}else if(pos[q1] < pos_r && pos[q2] < pos_r){ //q1 q2 都在左子树
Create(preL + 1, preL + numL, inL, pos_r - 1, q1, q2);
}else if(pos[q1] < pos_r || pos[q2] < pos_r){ //q1 q2 一左一右,GET!
printf("LCA of %d and %d is %d.\n", q1, q2, r);
flg = false;
}else{ //q1 q2 都在右子树
Create(preL + numL + 1, preR, pos_r + 1, inR, q1, q2);
}
}
}
int main(){
int nv, nq, tmp;
scanf("%d %d", &nq, &nv);
for(int i = 1; i <= nv; ++i){
scanf("%d", &in[i]);
pos[in[i]] = i;
}
for(int i = 1; i <= nv; ++i){
scanf("%d", &pre[i]);
}
for(int i = 0; i < nq; ++i){
int q1, q2;
scanf("%d %d", &q1, &q2);
if(pos[q1] * pos[q2] > 0){
flg = true; // 剪枝,样例4 能省100ms
Create(1, nv, 1, nv, q1, q2);
}else if(pos[q1] + pos[q2] > 0){
printf("ERROR: %d is not found.\n", pos[q1] ? q2 : q1);
}else{
printf("ERROR: %d and %d are not found.\n", q1, q2);
}
}
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
vector<int> in, pre;
unordered_map<int, bool> mp;
unordered_map<int, int> in_ord;
bool flg;
void Create(int preL, int preR, int inL, int inR, int q1, int q2)
{
if(preL >= preR || flg) return;
int r = pre[preL];
if(r == q1 || r == q2)
{
printf("%d is an ancestor of %d.\n", r , r == q1 ? q2 : q1);
flg = true;
}else if((in_ord[r] - in_ord[q1]) * (in_ord[r] - in_ord[q2]) < 0)
{
printf("LCA of %d and %d is %d.\n", q1, q2, r);
flg = true;
}
int numL = in_ord[r] - inL, numR = inR - in_ord[r] - 1;
if(numL > 0)
Create(preL+1, preL+1+numL, inL, in_ord[r], q1, q2);
if(numR > 0)
Create(preL+1+numL, preR, in_ord[r]+1, inR, q1, q2);
}
int main()
{
int nq, n;
scanf("%d %d", &nq, &n);
in.resize(n); pre.resize(n);
for(int i = 0; i < n; ++i)
{
scanf("%d", &in[i]);
mp[in[i]] = true;
in_ord[in[i]] = i;
}
for(int i = 0; i < n; ++i)
{
scanf("%d", &pre[i]);
}
for(int i = 0; i < nq; ++i)
{
int q1, q2;
scanf("%d %d", &q1, &q2);
if(mp[q1] & mp[q2] == true)
{
flg = false;
Create(0, n, 0, n, q1, q2);
}else if(mp[q1] || mp[q2])
{
printf("ERROR: %d is not found.\n", mp[q1] ? q2 : q1);
}else
{
printf("ERROR: %d and %d are not found.\n", q1, q2);
}
}
return 0;
}
- T4 code:
#include <bits/stdc++.h>
using namespace std;
vector<int> pre, in;
unordered_map<int, int> pos_in;
unordered_map<int, bool> has;
void Create(int preL, int preR, int inL, int inR, bool & flg, int q1, int q2)
{
if(preL >= preR || flg) return;
int r = pre[preL], id = pos_in[r], numL = id - inL, pos1 = pos_in[q1], pos2 = pos_in[q2];
int upper = max(pos1, pos2), lower = min(pos1, pos2);
if(id == pos1 || id == pos2)
{
if(id == pos2) swap(q1, q2);
printf("%d is an ancestor of %d.\n", q1, q2);
flg = true;
}else if(lower < id && id < upper)
{
printf("LCA of %d and %d is %d.\n", q1, q2, r);
flg = true;
}
Create(preL+1, preL+1+numL, inL, inL+numL, flg, q1, q2);
Create(preL+1+numL, preR, inL+numL+1, inR, flg, q1, q2);
}
int main()
{
int nq, n;
scanf("%d %d", &nq, &n);
in.resize(n); pre.resize(n);
for(int i = 0; i < n; ++i)
{
scanf("%d", &in[i]);
pos_in[in[i]] = i;
has[in[i]] = true;
}
for(int i = 0; i < n; ++i) scanf("%d", &pre[i]);
for(int i = 0; i < nq; ++i)
{
int q1, q2;
scanf("%d %d", &q1, &q2);
if(has[q1] && has[q2])
{
bool flg = false;
Create(0, n, 0, n, flg, q1, q2);
}else if(has[q1] || has[q2])
{
printf("ERROR: %d is not found.\n", has[q1] ? q2 : q1);
}else
{
printf("ERROR: %d and %d are not found.\n", q1, q2);
}
}
return 0;
}