Wednesday, October 31, 2012

Lowest Common Ancestor (LCA)

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define siz 1000005
int L[siz],section[siz],P[siz],color[siz];
int N,E;
vector <int> vec[siz];
void reset(){
    for(int i=0;i<=N;i++){
        color[i]=0;
        vec[i].clear();
    }
}
void dfs(int n){
    color[n]=1;
    for(int i=0;i<vec[n].size();i++){
        int v=vec[n][i];
        if(color[v]==0){
            P[v]=n;
            L[v]=L[n]+1;
            if(L[v]%2==0) section[v]=P[v];
            else section[v]=section[P[v]];
            color[v]=1;
            dfs(v);
        }
    }
    color[n]=2;
}

int LCA(int x, int y){
    if(x==y) return x;
    if(section[x]==section[y]&&L[x]==L[y]){
        if(P[x]==P[y]) return P[x];
        else return section[x];
    }

    if(section[x]!=section[y]){
        if(section[x]>section[y]) LCA(section[x],y);
        else LCA(section[y],x);
    }

    if(L[x]!=L[y]){
        if(L[x]>L[y]) LCA(P[x],y);
        else LCA(x,P[y]);
    }
}

int main()
{
    int x,y;
    freopen("input.txt","r",stdin);
    while(scanf("%d%d",&N,&E)==2){
        reset();
        for(int i=0;i<E;i++){
            scanf("%d%d",&x,&y);
            vec[x].push_back(y);
            vec[y].push_back(x);
        }

        P[1]=L[1]=section[1]=0;
        for(int i=1;i<=N;i++) if(color[i]==0) dfs(i);

        while(scanf("%d%d",&x,&y)==2){
            if(x==0&&y==0) break;
            cout<<LCA(x,y)<<endl;
        }


//        for(int i=1;i<=N;i++){
//            cout<<section[i]<<" "<<L[i]<<" "<<i<<endl;
//        }
    }
    return 0;
}

No comments:

Post a Comment