LZ做题太少,一开始只想到建树、然后分别找到两个元素所在的分支序列、然后找到第一个公共元素这种方法,提交之后得到22分,最后两个测试点超时;后来参考大佬https://blog.csdn.net/qq_41317652/article/details/82557975的方法,原来lca只需要一次遍历就ok了,不需要找两个序列,下面附上我的22分代码(第2段代码)和AC代码(第1段代码);
#include<bits/stdc++.h>
using namespace std;
const int MAXN=10003;
struct Node{
int data;
Node* left;
Node* right;
};
vector<int> in,pre;
int fa[MAXN];
int m,n;
Node* build(int inl,int inr,int prel,int prer){
if(prel>prer) return NULL;
Node* root=new Node;
root->data=pre[prel];
root->left=root->right=NULL;
int k;
for(int i=inl;i<=inr;i++){
if(in[i]==pre[prel]){
k=i;break;
}
}
int numleft=k-inl;
root->left=build(inl,k-1,prel+1,prel+numleft);
root->right=build(k+1,inr,prel+numleft+1,prer);
return root;
}
bool findnode(int x){
for(int i=0;i<n;i++){
if(pre[i]==x) return true;
}
return false;
}
Node* lca(Node* root,int a,int b){
if(root==NULL) return NULL;
if(root->data==a||root->data==b) return root;
Node* l=lca(root->left,a,b);
Node* r=lca(root->right,a,b);
if(l&&r) return root;
if(!l&&r) return r;
if(l&&!r) return l;
}
int main()
{
freopen("in.txt","r",stdin);
cin>>m>>n;
for(int i=0;i<=10002;i++) fa[i]=i;
in.resize(n);pre.resize(n);
for(int i=0;i<n;i++){
cin>>in[i];
}
for(int i=0;i<n;i++){
cin>>pre[i];
}
Node* root=build(0,n-1,0,n-1);
for(int i=0;i<m;i++){
int a,b;cin>>a>>b;
int flaga=0,flagb=0;
if(!findnode(a)) flaga=1;
if(!findnode(b)) flagb=1;
if(flaga==1&&flagb==1) {printf("ERROR: %d and %d are not found.\n", a, b);continue;}
if(flaga==1&&flagb==0) {printf("ERROR: %d is not found.\n", a);continue;}
if(flaga==0&&flagb==1) {printf("ERROR: %d is not found.\n", b);continue;}
Node* si=lca(root,a,b);
if(si->data==a) {
cout<<a<<" is an ancestor of "<<b<<"."<<endl;continue;
}
if(si->data==b) {
cout<<b<<" is an ancestor of "<<a<<"."<<endl;continue;
}
if(si->data!=a&&si->data!=b) {
cout<<"LCA of "<<a<<" and "<<b<<" is "<<si->data<<"."<<endl;continue;
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
//const int MAXN=10003;//会出现段错误
struct Node{
int data;
Node* left;
Node* right;
};
vector<int> in,pre;
//int fa[MAXN];
map<int,int> fa;//改成map避免段错误,即数组越界
int m,n;
Node* build(int inl,int inr,int prel,int prer){
if(prel>prer) return NULL;
Node* root=new Node;
root->data=pre[prel];
root->left=root->right=NULL;
int k;
for(int i=inl;i<=inr;i++){
if(in[i]==pre[prel]){
k=i;break;
}
}
int numleft=k-inl;
root->left=build(inl,k-1,prel+1,prel+numleft);
root->right=build(k+1,inr,prel+numleft+1,prer);
return root;
}
void pretra(Node* root){
if(root==NULL) return;
if(root->left!=NULL) fa[root->left->data]=root->data;
if(root->right!=NULL) fa[root->right->data]=root->data;
pretra(root->left);
pretra(root->right);
}
bool findnode(int x){
for(int i=0;i<n;i++){
if(pre[i]==x) return true;
}
return false;
}
int main()
{
freopen("in.txt","r",stdin);
cin>>m>>n;
//for(int i=0;i<=10002;i++) fa[i]=i;
in.resize(n);pre.resize(n);
for(int i=0;i<n;i++){
cin>>in[i];
}
for(int i=0;i<n;i++){
cin>>pre[i];
fa[pre[i]]=pre[i];
}
Node* root=build(0,n-1,0,n-1);
pretra(root);
for(int i=0;i<m;i++){
int a,b;cin>>a>>b;
int flaga=0,flagb=0;
if(!findnode(a)) flaga=1;
if(!findnode(b)) flagb=1;
if(flaga==1&&flagb==1) {cout<<"ERROR: "<<a<<" and "<<b<<" are not found."<<endl;continue;}
if(flaga==1&&flagb==0) {cout<<"ERROR: "<<a<<" is not found."<<endl;continue;}
if(flaga==0&&flagb==1) {cout<<"ERROR: "<<b<<" is not found."<<endl;continue;}
vector<int> p1,p2;
int xa=a,xb=b;
while(fa[xa]!=xa){
p1.push_back(xa);
xa=fa[xa];
}
p1.push_back(xa);
while(fa[xb]!=xb){
p2.push_back(xb);
xb=fa[xb];
}
p2.push_back(xb);
map<int,int> mp;int si;
for(int k=0;k<p1.size();k++){
mp[p1[k]]=1;
}
for(int k=0;k<p2.size();k++){
if(mp[p2[k]]==1) {
si=p2[k];break;
}
}
if(si==a) {
cout<<a<<" is an ancestor of "<<b<<"."<<endl;continue;
}
if(si==b) {
cout<<b<<" is an ancestor of "<<a<<"."<<endl;continue;
}
if(si!=a&&si!=b) {
cout<<"LCA of "<<a<<" and "<<b<<" is "<<si<<"."<<endl;continue;
}
}
return 0;
}