Cod sursa(job #996358)

Utilizator assa98Andrei Stanciu assa98 Data 11 septembrie 2013 17:58:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <vector>
using namespace std;

struct sp {
    int a, i;
    sp() {
        a=i=0;
    }
    sp(int x,int y) {
        a=x;
        i=y;
    }
};

const int MAX_N=100100;
const int MAX_M=2000100;


int h[MAX_N];
int dad[MAX_N];
int viz[MAX_N];
int anc[MAX_N];

int ans[MAX_M];

vector<int> A[MAX_N];

vector<sp> Q[MAX_N];

int str(int nod) {
    if(dad[nod]==nod)
        return nod;
    return dad[nod]=str(dad[nod]);
}

void merge(int x,int y) {
    int dx=str(x);
    int dy=str(y);
    if(dx==dy)
        return ;
    if(h[dx]<h[dy]) {
        dad[dx]=dy;
    }
    else if(h[dx]>h[dy]) {
        dad[dy]=dx;
    }
    else {
        dad[dy]=dx;
        h[dx]++;
    }
}

void dfs(int nod) {
    dad[nod]=nod;
    h[nod]=1;
    anc[nod]=nod;    

    for(vector<int>::iterator it=A[nod].begin();it!=A[nod].end();it++) {
        dfs(*it);
        merge(nod,*it);
        anc[str(nod)]=nod;
    }
    
    viz[nod]=1;
    for(vector<sp>::iterator it=Q[nod].begin(); it!=Q[nod].end(); it++) {
       if(viz[it->a]) {
           ans[it->i]=anc[str(it->a)];
       }
    }
}


int main() {
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n;i++) {
        int nod;
        scanf("%d",&nod);
        A[nod].push_back(i);
    }

    for(int i=1;i<=m;i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        Q[x].push_back(sp(y,i));
        Q[y].push_back(sp(x,i));
    }

    dfs(1);

    for(int i=1;i<=m;i++) {
        printf("%d\n",ans[i]);
    }
    return 0;
}