先判断两个点是否在树中,若不是则直接就找不到
若在树中,则DFS搜索连个点所在的路径,搜到了两个路径,在找两个路径最开始的相同点,也就是最近祖先结点
PS:吐槽,题目数据中结点会有相同的情况,所以用前驱寻找时会出现死循环!注意先
#include<stdio.h> #include<stack> #include<iostream> using namespace std; struct TREE{ int v; TREE *left,*right; }*rhead; int shu[10009],all=0; void bulid(TREE *head){ int temp; scanf("%d",&temp); if(temp==0){ head->left=NULL; head->right=NULL; head->v=0; return; }else{ shu[temp]=1; head->v=temp; head->left=new TREE; bulid(head->left); head->right=new TREE; bulid(head->right); } } int Apre[10099],Bpre[10999]; int fa,fb,oka,okb; void finda(TREE *head){ if(oka==1)return; if(head->v==fa){ oka=1; return; } if(head->left->v!=0){ if(head->left->v!=head->v) Apre[head->left->v]=head->v; finda(head->left); } if(head->right->v!=0){ if(head->right->v!=head->v) Apre[head->right->v]=head->v; finda(head->right); } } void findb(TREE *head){ if(okb==1)return; if(head->v==fb){ okb=1; return; } if(head->left->v!=0){ if(head->left->v!=head->v) Bpre[head->left->v]=head->v; findb(head->left); } if(head->right->v!=0){ if(head->right->v!=head->v) Bpre[head->right->v]=head->v; findb(head->right); } } void freeTree(TREE *head ){ if(head->left!=NULL) freeTree(head->left); if(head->right!=NULL) freeTree(head->right); delete head; head=NULL; } int main(){ int t; while(scanf("%d",&t)!=EOF) while(t--){ int i; stack<int>sta,stb; for(i=0;i<=10000;i++){ shu[i]=0; Apre[i]=-1; Bpre[i]=-1; } rhead=new TREE; TREE *head=rhead; bulid(head); oka=0;okb=0; scanf("%d%d",&fa,&fb); if(shu[fa]==0||shu[fb]==0){ printf("My God "); }else{ finda(rhead); findb(rhead); int p=fa; sta.push(p); while(Apre[p]!=-1){ p=Apre[p]; sta.push(p); // if(Apre[p]==p)break; } p=fb; stb.push(p); while(Bpre[p]!=-1){ p=Bpre[p]; stb.push(p); // if(Bpre[p]==p)break; } int root=-1; while((!sta.empty())&&(!stb.empty())&&(sta.top()==stb.top())){ root=sta.top(); sta.pop(); stb.pop(); } if(root==-1)printf("My God "); else printf("%d ",root); freeTree(rhead); } } return 0; }