POJ1330 LCA/给树的节点标记层数

来源:互联网 发布:淘宝一键复制有坏处吗 编辑:程序博客网 时间:2024/05/29 19:40

1 题意,求LCA——Least Common Ancestors,最近公共祖先。

2 分析

代码二,先dfs将各个节点的层数标记上。

代码一,标记一下数组。

代码一,16ms

#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;const int maxn=10010;int parent[maxn];int vis[maxn];int Find(int a,int b){    //分开便利OR一步一ch    while(!vis[a]){        vis[a]=1;        if(-1!=parent[a])            a=parent[a];    }    while(!vis[b]){        b=parent[b];    }    return b;}int main(){    int kk;    scanf("%d",&kk);    while(kk--){        int n,a,b;        memset(parent,-1,sizeof(parent));        memset(vis,0,sizeof(vis));        scanf("%d",&n);        for(int i=1;i<n;i++){            scanf("%d%d",&a,&b);            parent[b]=a;        }        scanf("%d%d",&a,&b);        int res=Find(a,b);        cout<<res<<endl;    }}

代码二,60ms

#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#include <vector>using namespace std;const int maxn=10010;int parent[maxn];vector <int> son[maxn];int r[maxn];//????????void DLR(int root,int step){    r[root]=step;//    for(int i=0;i<son[root].size();i++)        DLR(son[root][i],step+1);}int Find(int a,int b){    while(a!=b){        if(r[a]>r[b]&&parent[a]!=-1)            a=parent[a];        else if(r[a]<=r[b]&&parent[b]!=-1)            b=parent[b];    }    return a;}int main(){    int kk;    scanf("%d",&kk);    while(kk--){        int n,a,b;        for(int i=0;i<maxn;i++){            son[i].clear();            r[i]=-1;            parent[i]=-1;        }        scanf("%d",&n);        for(int i=1;i<n;i++){            scanf("%d%d",&a,&b);            son[a].push_back(b);            parent[b]=a;        }        int root=1;        for(root=1;parent[root]!=-1;root++);//?????????????????1,2,...n        DLR(root,0);//DLR??????data(?) left right;0???        scanf("%d%d",&a,&b);        int res=Find(a,b);        cout<<res<<endl;    }}


0 0