Cod sursa(job #1190167)

Utilizator mihai995mihai995 mihai995 Data 24 mai 2014 17:09:50
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <fstream>
#include <vector>
using namespace std;

#define forit(it,v) for (auto it = v.begin() ; it != v.end() ; it++)

const int N = 1 + 1e5;

int head[N], n;
int start[N], stop[N], timp;
vector<int> tree[N];

void mark(int x, int H){
    head[x] = H;
    forit(it, tree[x])
        if ( !head[*it] )
            mark(*it, H);
}

int dfs(int x){
    start[x] = ++timp;

    int weight = 1, best = -1, val, son;
    forit(it, tree[x]){
        val = dfs(*it);
        weight += val;
        if (best < val){
            best = val;
            son = *it;
        }
    }
    forit(it, tree[x])
        if (*it != son)
            mark(*it, x);
    stop[x] = ++timp;

    return weight;
}

inline int isAncestor(int T, int x){
    return start[T] <= start[x] && stop[x] <= stop[T];
}

int lca(int a, int b){
    int x = a, y = b;
    while (!isAncestor(x, y) && !isAncestor(y, x)){
        x = head[x];
        y = head[y];
    }
    if (isAncestor(y, x))
        swap(x, y);
   return (isAncestor(y, a) && isAncestor(y, b)) ? y : x;
}

int main(){
    int nrQ, x, y;
    ifstream in("lca.in");

    in >> n >> nrQ;
    for (int i = 2 ; i <= n ; i++){
        in >> x;
        tree[x].push_back(i);
    }

    dfs(1);
    mark(1, 1);

    ofstream out("lca.out");

    while (nrQ--){
        in >> x >> y;
        out << lca(x, y) << '\n';
    }

    in.close();
    out.close();

    return 0;
}