1143. Lowest Common Ancestor (30)

1143. Lowest Common Ancestor (30)

见过最简单的一个代码

#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,a;
map<int,bool>q;

int main(){
    scanf("%d%d",&m,&n);
    vector<int>pre(n);
    for(int i=0;i<n;i++){
        scanf("%d",&pre[i]);
        q[pre[i]]=true;
    }
    for(int i=0;i<m;i++){
        scanf("%d%d",&u,&v);
        for(int j=0;j<n;j++){
            a=pre[j];
            if((v>a&&a>u)||(u>a&&a>v)||(u==a)||(v==a))break;
        }
        if(q[u]==false&&q[v]==false)printf("ERROR: %d and %d are not found.\n",u,v);
        else if(q[u]==false||q[v]==false)printf("ERROR: %d is not found.\n",q[u]==false?u:v);
        else if(u==a||v==a)printf("%d is an ancestor of %d.\n",a,u==a?v:u);
        else printf("LCA of %d and %d is %d.\n",u,v,a);
    }
    return 0;
}

代码参考:https://www.liuchuo.net/archives/4616

前序建树,求最近公共祖先

#include<bits/stdc++.h>  
using namespace std;  
  
const int MAXN = 10005;  
const double eps = 1e-8;  
  
struct Node{  
    int l, r;  
    int val;  
    Node() : l(-1), r(-1) {};  
}node[MAXN];  
  
  
void preOrder(int l, int r) {  
    if(l <= r) {  
        //二叉搜索树,第一个点是根节点  
        int l2 = r + 1;     //若有右子树,l2小于等于r  
        for(int i = l + 1; i <= r; ++i)  
            if(node[l].val < node[i].val) {  
                l2 = i;  
                break;  
            }  
        if((l2 <= r && l < l2 - 1) || (l2 > r) && (l < r))  
            node[l].l = l + 1;  
        if(l2 <= r)  
            node[l].r = l2;  
        if(l2 <= r)  
            preOrder(l + 1, l2 - 1);  
        else  
            preOrder(l + 1, r);  
        preOrder(l2, r);  
    }  
}  
int main() {  
    //freopen("/1.txt", "r", stdin);  
    int m, n, u, v, ui, vi, anc;  
    vector<int> vec;  
  
    scanf("%d%d", &m, &n);  
    for(int i = 0; i < n; ++i)  
        scanf("%d", &node[i].val);  
    preOrder(0, n - 1);  
//    for(int i = 0; i < n; ++i)  
//        printf("%d %d %d\n", node[i].val, node[i].l, node[i].r);  
    while(m--) {  
        scanf("%d%d", &u, &v);  
        vec.clear();  
        ui = vi = 0;  
        while(true) {  
            vec.push_back(node[ui].val);       //将寻找u的途中,经过的节点值都存储起来  
            if(u == node[ui].val)  
                break;  
            if(u < node[ui].val)  
                ui = node[ui].l;  
            else  
                ui = node[ui].r;  
            if(ui == -1)  
                break;  
        }  
        int k = 0;  
        while(true) {  
            //k可以理解成层数,若是u,v的共同祖先,它一定在同一层上;不断更新anc,能找到u,v的最近的祖先  
            if(k < vec.size() && node[vi].val == vec[k])  
                anc = vec[k];  
            ++k;  
            if(v == node[vi].val)  
                break;  
            if(v < node[vi].val)  
                vi = node[vi].l;  
            else  
                vi = node[vi].r;  
            if(vi == -1)  
                break;  
        }  
        if(ui > -1 && vi > -1) {  
            if(anc == u)  
                printf("%d is an ancestor of %d.\n", anc, v);  
            else if(anc == v)  
                printf("%d is an ancestor of %d.\n", anc, u);  
            else  
                printf("LCA of %d and %d is %d.\n", u, v, anc);  
        }  
        else {  
            if(ui == -1 && vi == -1)  
                printf("ERROR: %d and %d are not found.\n", u, v);  
            else if(ui == -1)  
                printf("ERROR: %d is not found.\n", u);  
            else  
                printf("ERROR: %d is not found.\n", v);  
        }  
    }  
    return 0;  
}  

code from——  http://blog.csdn.net/lucky1521/article/details/79604604



#include<bits/stdc++.h>
const int maxn =100100;
using namespace std;
struct TreeNode{
    int val;
    TreeNode *left,*right;
    TreeNode(int v):val(v),left(NULL),right(NULL){}
};

int pre[maxn],ino[maxn];
TreeNode *build(int preL,int preR,int inoL,int inoR){
    if(preL>preR)return NULL;
    int e=pre[preL],idx=inoL;
    while(idx<=inoR&&e!=ino[idx])++idx;
    TreeNode *r=new TreeNode(e);
    r->left=build(preL+1,preL+1+idx-1-inoL,inoL,idx-1);
    r->right=build(preR+idx+1-inoR,preR,idx+1,inoR);
    return r;
}

TreeNode *search(TreeNode *r,int e){
    while(r){
        if(e<r->val)r=r->left;
        else if(e>r->val)r=r->right;
        else return r;
    }
    return r;
}

TreeNode *LCA(TreeNode *r, TreeNode *px, TreeNode *py){
   while((r->val-px->val)*(r->val-py->val)>0)        r=(r->val<px->val)?r->right:r->left;
    return r;
}


int main()
{
    int m,n;
    scanf("%d %d",&m,&n);
    for(int i=0;i<n;++i){
        scanf("%d",pre+i);
        ino[i]=pre[i];
    }
    sort(ino,ino+n);
    TreeNode *r=build(0,n-1,0,n-1);
    while(m--){
        int x,y;
        scanf("%d %d",&x,&y);
        TreeNode *px=search(r,x),*py=search(r,y);
        if(!px&&!py) printf("ERROR: %d and %d are not found.\n",x,y);
        else if(!(px&&py)) printf("ERROR: %d is not found.\n",px?y:x);
        else{
            TreeNode *res=LCA(r,px,py);
            if(res==px) printf("%d is an ancestor of %d.\n",px->val,py->val);
            else if(res==py) printf("%d is an ancestor of %d.\n",py->val,px->val);
            else printf("LCA of %d and %d is %d.\n",px->val,py->val,res->val);
        }
    }
    return 0;
}
code from -http://blog.csdn.net/gl486546/article/details/79607570
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值