1143 Lowest Common Ancestor(建树与不建两种思路)
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1143 Lowest Common Ancestor(建树与不建两种思路)相关的知识,希望对你有一定的参考价值。
目录
解法一
这题可以不建树,直接利用BST的性质:左子树<根节点<右子树,对先序序列进行遍历,如果有某个元素大于等于u,v中较小的且小于等于u,v中较大的,则可能是根节点。
这题数据弱,直接认为这样的点是根节点也AC了。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<set>
#include<string>
using namespace std;
typedef long long LL;
const int maxn = 10007;
const int MOD = 1000000007;
const int INF = 1000000000;//INF:下确界
const LL SUP = (1LL<<63)-1;//SUP:上确界
const double eps = 1e-5;
int A[maxn];
int n;
map<int,int> eximp;
int main(){
int pNum;
cin>>pNum>>n;
for(int i=0;i<n;i++){
cin>>A[i];
eximp[A[i]] = 1;
}
while(pNum--){
int v1,v2;
cin>>v1>>v2;
if(eximp[v1]==0||eximp[v2]==0){
if(eximp[v1]==1)printf("ERROR: %d is not found.\\n",v2);
else if(eximp[v2]==1)printf("ERROR: %d is not found.\\n",v1);
else printf("ERROR: %d and %d are not found.\\n",v1,v2);
continue;
}
int LCA;
for(int i=0;i<n;i++){
LCA = A[i];
if(LCA>=min(v1,v2)&&LCA<=max(v1,v2))break;
}
if(LCA==v1||LCA==v2)printf("%d is an ancestor of %d.\\n",LCA==v1?v1:v2,LCA==v1?v2:v1);
else printf("LCA of %d and %d is %d.\\n",v1,v2,LCA);
}
return 0;
}
解法二
我尝试建树,然后用缩短系谱的通法找LCA,但是超时了。
代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<set>
#include<string>
using namespace std;
typedef long long LL;
const int maxn = 10007;
const int MOD = 1000000007;
const int INF = 1000000000;//INF:下确界
const LL SUP = (1LL<<63)-1;//SUP:上确界
const double eps = 1e-5;
int A[maxn];
int n;
map<int,int> eximp;
struct Node{
int v;
Node *lchild,*rchild,*pa;
};
map<Node*,int> noToV;
map<int,Node*> vToNo;
void insert(int x,Node* &root){
if(root==NULL){
root = new Node;
noToV[root] = x;
vToNo[x] = root;
root->v = x;
root->lchild = root->rchild = root->pa = NULL;
return;
}
if(root->v>x){
insert(x,root->lchild);
if(!root->lchild->pa)root->lchild->pa = root;
}
if(root->v<x){
insert(x,root->rchild);
if(!root->rchild->pa)root->rchild->pa = root;
}
}
int getLinkLen(Node* root){
int len = 1;
while(root->pa){
root = root->pa;
len ++;
}
return len;
}
Node* getLCA(Node* u,Node* v){
int uLen = getLinkLen(u);
int vLen = getLinkLen(v);
while(uLen<vLen){
v = v->pa;
vLen --;
}
while(vLen<uLen){
u = u->pa;
uLen --;
}
while(v!=u){
v = v->pa;
u = u->pa;
}
return v;
}
int main(){
int pNum;
cin>>pNum>>n;
for(int i=0;i<n;i++){
cin>>A[i];
eximp[A[i]] = 1;
}
Node* root = NULL;
for(int i=0;i<n;i++){
insert(A[i],root);
}
while(pNum--){
int v1,v2;
cin>>v1>>v2;
if(eximp[v1]==0||eximp[v2]==0){
if(eximp[v1]==1)printf("ERROR: %d is not found.\\n",v2);
else if(eximp[v2]==1)printf("ERROR: %d is not found.\\n",v1);
else printf("ERROR: %d and %d are not found.\\n",v1,v2);
continue;
}
int LCA;
Node* u = vToNo[v1];
Node* v = vToNo[v2];
LCA = noToV[getLCA(u,v)];
if(LCA==v1||LCA==v2)printf("%d is an ancestor of %d.\\n",LCA==v1?v1:v2,LCA==v1?v2:v1);
else printf("LCA of %d and %d is %d.\\n",v1,v2,LCA);
}
return 0;
}
结果
以上是关于1143 Lowest Common Ancestor(建树与不建两种思路)的主要内容,如果未能解决你的问题,请参考以下文章
1143. Lowest Common Ancestor (30)
PAT 1143 Lowest Common Ancestor
1143 Lowest Common Ancestor (30分)