大致题意就是给出一棵树的先序、中序遍历序列,可以构造一棵树。然后给两个顶点,找出这两个结点的最近公共祖先。
1 #include<iostream> 2 #include<unordered_map> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 10010; 6 int m,n,pre[maxn],in[maxn],u,v,flag; 7 unordered_map<int,int> pos; 8 9 void LCA(int inL,int inR,int preRoot,int u,int v) { 10 if(inL > inR) return ; 11 int inRoot = pos[pre[preRoot]],inU = pos[u],inV = pos[v]; 12 if((inU < inRoot && inRoot < inV)||(inU > inRoot && inRoot > inV)) 13 printf("LCA of %d and %d is %d.\n",u,v,in[inRoot]); 14 else if(inU == inRoot) 15 printf("%d is an ancestor of %d.\n",u,v); 16 else if(inV == inRoot) 17 printf("%d is an ancestor of %d.\n",v,u); 18 else if(inU < inRoot && inV < inRoot) //遍历左子树 19 LCA(inL,inRoot-1,preRoot+1,u,v); 20 else if(inU > inRoot && inV > inRoot) //遍历右子树 21 LCA(inRoot+1,inR,preRoot+1+(inRoot-inL),u,v); 22 } 23 24 int main() { 25 cin>>m>>n; 26 for(int i = 1; i <= n; ++i) scanf("%d",&in[i]),pos[in[i]] = i; 27 for(int i = 1; i <= n; ++i) scanf("%d",&pre[i]); 28 for(int i = 0; i < m; ++i) { 29 scanf("%d%d",&u,&v); 30 if(pos[u] == 0 && pos[v] == 0) printf("ERROR: %d and %d are not found.\n",u,v); 31 else if(pos[u] == 0||pos[v] == 0) printf("ERROR: %d is not found.\n",pos[u] == 0?u:v); 32 else LCA(1,n,1,u,v); 33 } 34 return 0; 35 }