LCA in a Binary Tree PAT甲級 - 1151
阿新 • • 發佈:2018-11-23
https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856
給定前序中序 還原二叉樹
用單調棧掃一遍前序 對於一個點 他的父節點的前序肯定小於它 如過棧頂節點的左子樹的中序區間包含當前節點 則當前節點為棧頂節點的左孩子 否則是右孩子 或者沒有父子關係則pop棧頂
這題有毒啊 給的前序中序不一定是1-n的全排列
#include <bits/stdc++.h> using namespace std; const int maxn=1e4+10; struct node { int id,l,r,m,flag; }; map <int,int> mp1,mp2; stack <node> stk; int ch[maxn][2],fa[maxn]; int pre[maxn],mid[maxn],pos[maxn],lef[maxn],rgt[maxn],deep[maxn]; int n,q,num; int getlca(int u,int v) { if(deep[u]<deep[v]) swap(u,v); while(!(lef[u]<=pos[v]&&pos[v]<=rgt[u])) u=fa[u]; return u; } int main() { node cur,tmp; int i,u,v,uu,vv,lca; scanf("%d%d",&q,&n); for(i=1;i<=n;i++){ scanf("%d",&mid[i]); num++; mp1[mid[i]]=num,mp2[num]=mid[i]; pos[num]=i; } for(i=1;i<=n;i++){ scanf("%d",&pre[i]); pre[i]=mp1[pre[i]]; } tmp.id=pre[1],tmp.l=1,tmp.r=n,tmp.m=pos[pre[1]],tmp.flag=0; stk.push(tmp); lef[pre[1]]=1,rgt[pre[1]]=n; for(i=2;i<=n;i++){ while(!stk.empty()){ cur=stk.top(); stk.pop(); if(cur.flag==0){ cur.flag=1; if(cur.l<=pos[pre[i]]&&pos[pre[i]]<=cur.m-1){ ch[cur.id][0]=pre[i],fa[pre[i]]=cur.id; stk.push(cur); tmp.id=pre[i],tmp.l=cur.l,tmp.r=cur.m-1,tmp.m=pos[pre[i]],tmp.flag=0; stk.push(tmp); lef[pre[i]]=tmp.l,rgt[pre[i]]=tmp.r,deep[pre[i]]=deep[cur.id]+1; break; } } if(cur.flag==1){ if(cur.m+1<=pos[pre[i]]&&pos[pre[i]]<=cur.r){ ch[cur.id][1]=pre[i],fa[pre[i]]=cur.id; tmp.id=pre[i],tmp.l=cur.m+1,tmp.r=cur.r,tmp.m=pos[pre[i]],tmp.flag=0; stk.push(tmp); lef[pre[i]]=tmp.l,rgt[pre[i]]=tmp.r,deep[pre[i]]=deep[cur.id]+1; break; } } } } while(q--){ scanf("%d%d",&uu,&vv); u=mp1[uu],v=mp1[vv]; if(!u&&!v) printf("ERROR: %d and %d are not found.\n",uu,vv); else if(!u&&v) printf("ERROR: %d is not found.\n",uu); else if(u&&!v) printf("ERROR: %d is not found.\n",vv); else{ lca=getlca(u,v); if(lca==u) printf("%d is an ancestor of %d.\n",uu,vv); else if(lca==v) printf("%d is an ancestor of %d.\n",vv,uu); else printf("LCA of %d and %d is %d.\n",uu,vv,mp2[lca]); } } return 0; }