7-14 二叉搜索樹的最近公共祖先 (30 分)


題目鏈接:https://pintia.cn/problem-sets/1110382478542622720/problems/1110382589284831244

題目大意:

給定一棵二叉搜索樹的先序遍歷序列,要求你找出任意兩結點的最近公共祖先結點(簡稱 LCA)。

輸入格式:

輸入的第一行給出兩個正整數:待查詢的結點對數 M(≤ 1 000)和二叉搜索樹中結點個數 N(≤ 10 000)。隨后一行給出 N 個不同的整數,為二叉搜索樹的先序遍歷序列。最后 M 行,每行給出一對整數鍵值 U 和 V。所有鍵值都在整型int范圍內。

輸出格式:

對每一對給定的 U 和 V,如果找到 A 是它們的最近公共祖先結點的鍵值,則在一行中輸出 LCA of U and V is A.。但如果 U 和 V 中的一個結點是另一個結點的祖先,則在一行中輸出 X is an ancestor of Y.,其中 X 是那個祖先結點的鍵值,Y 是另一個鍵值。如果 二叉搜索樹中找不到以 U 或 V 為鍵值的結點,則輸出 ERROR: U is not found. 或者 ERROR: V is not found.,或者 ERROR: U and V are not found.

具體思路:如果是一棵二叉樹的先序遍歷的話,是建不出樹來的,但是這是一顆二叉搜索樹,滿足左小右大,所以就可以建出樹來了。然后建樹的時候,保存每個節點的左節點,右節點,父親節點。判斷lca的時候,我們對當前的點往上搜就可以了。

注意離散化的下標。

AC代碼:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 const int maxn = 2e4+100;
  5 struct node
  6 {
  7     int lt;
  8     int rt;
  9     int fa;
 10 } q[maxn];
 11 int a[maxn],b[maxn];
 12 void add(int rt,int val)
 13 {
 14     if(!rt)
 15         return ;
 16     if(rt>val)
 17     {
 18         if(q[rt].lt)
 19             add(q[rt].lt,val);
 20         else
 21         {
 22             q[rt].lt=val;
 23             q[val].fa=rt;
 24             return ;
 25         }
 26     }
 27     else
 28     {
 29         if(q[rt].rt)
 30             add(q[rt].rt,val);
 31         else
 32         {
 33             q[rt].rt=val;
 34             q[val].fa=rt;
 35             return ;
 36         }
 37     }
 38 }
 39 int vis[maxn],ans;
 40 void  Find(int t)
 41 {
 42     if(!t)
 43         return ;
 44     if(vis[t])
 45     {
 46         ans=t;
 47         return ;
 48     }
 49     vis[t]=1;
 50     Find(q[t].fa);
 51 }
 52 int main()
 53 {
 54     int n,m;
 55     scanf("%d %d",&m,&n);
 56     for(int i=0; i<=10000; i++)
 57     {
 58         q[i].lt=0;
 59         q[i].rt=0;
 60         q[i].fa=0;
 61     }
 62     for(int i=1; i<=n; i++)
 63     {
 64         scanf("%d",&a[i]);
 65         b[i]=a[i];
 66     }
 67     sort(b+1,b+n+1);
 68     int rt;
 69     for(int i=1; i<=n; i++)
 70     {
 71         a[i]=lower_bound(b+1,b+n+1,a[i])-b;
 72         if(i==1)
 73             rt=a[i];
 74         else
 75             add(rt,a[i]);
 76     }
 77     for(int i=1; i<=m; i++)
 78     {
 79         int st,ed;
 80         scanf("%d %d",&st,&ed);
 81         int s1=lower_bound(b+1,b+n+1,st)-b;
 82         int s2=lower_bound(b+1,b+n+1,ed)-b;
 83         if(b[s1]!=st&&b[s2]!=ed)
 84             printf("ERROR: %d and %d are not found.\n",st,ed);
 85         else if(b[s1]!=st)
 86             printf("ERROR: %d is not found.\n",st);
 87         else if(b[s2]!=ed)
 88             printf("ERROR: %d is not found.\n",ed);
 89         else
 90         {
 91             Find(s1);
 92             if(vis[s2])
 93                 printf("%d is an ancestor of %d.\n",ed,st);
 94             else
 95             {
 96                 Find(s2);
 97                 if(ans==s1)
 98                     printf("%d is an ancestor of %d.\n",st,ed);
 99                 else
100                     printf("LCA of %d and %d is %d.\n",st,ed,b[ans]);
101             }
102         }
103         memset(vis,0,sizeof(vis));
104         ans=0;
105     }
106 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM