码迷,mamicode.com
首页 > 其他好文 > 详细

LCA

时间:2016-05-22 12:09:02      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:

///Nearest Common Ancestors
/// 1330
#include <cstdio>
#include <map>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 10000+10;
int t,n;
vector<int> v[maxn],Q[maxn];
int p[maxn];
int ind[maxn];
int ancester[maxn];
int vis[maxn];
int make_set(int x){
    p[x]=x;
}
int find_set(int a){
    return a==p[a]?a:find_set(p[a]);
}

int union_set(int a,int b){
    int pa = find_set(a);
    int pb = find_set(b);
    if(pa != pb){
        p[pb] = pa;
    }
}

void LCA(int t){
    make_set(t);
    ancester[t]=t;
    for(int i=0;i<v[t].size();i++){
        LCA(v[t][i]);
        union_set(t,v[t][i]);
        ancester[v[t][i]] = t;
    }
    vis[t] = 1;
    for(int i=0;i<Q[t].size();i++){
        if(vis[Q[t][i]] == 1){
            printf("%d\n",ancester[find_set(Q[t][i])]);
            return;
        }
    }
}

int main(){
    scanf("%d",&t);
    while(t--){
        memset(ind,0,sizeof(ind));
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            v[i].clear();
            Q[i].clear();
        }
        for(int i=0;i<n-1;i++){
            int U,V;
            scanf("%d %d",&U,&V);
            v[U].push_back(V);
            ind[V]+=1;
        }
        int q1,q2;
        scanf("%d %d",&q1,&q2);
        ///查询集合{u,v},
        ///我们构造临界表u->v,v->u,
        ///这样我们用u可以调用v,用v调用u,
        ///模拟函数f(x),
        ///定义f,基数为2的集合V中f(x)=V-x.
        Q[q1].push_back(q2);
        Q[q2].push_back(q1);
        for(int i=1;i<=n;i++){
            if(!ind[i]){
                LCA(i);
            }
        }
    }
    return 0;
}

 

LCA

标签:

原文地址:http://www.cnblogs.com/Lxyan/p/5516468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!