Cod sursa(job #369478)

Utilizator MariusMarius Stroe Marius Data 28 noiembrie 2009 15:02:23
Problema Lowest Common Ancestor Scor Ascuns
Compilator cpp Status done
Runda Marime 1.72 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cassert>
#include <iostream>

using namespace std;

const char iname[] = "lca.in";
const char oname[] = "lca.out";

const int MAX_N = 100005;
const int MAX_M = 2000005;

vector <int> adj[MAX_N], ancestor(MAX_N), parent(MAX_N), answers(MAX_M);
vector < pair <int, int> > pairs[MAX_N];
vector <bool> color(MAX_N, false);

int find(int u) {
    if (u != parent[u])  parent[u] = find(parent[u]);
    return parent[u];
}

void uniq(int u, int v) {
    (rand() & 1) ? parent[u] = v : parent[v] = u;
}

void DF(int u) {
    vector <int>::iterator it;
    vector < pair <int, int> >::iterator itp;

    parent[u] = u;
    ancestor[find(u)] = u;
    for (it = adj[u].begin(); it != adj[u].end(); ++ it) {
        DF(*it);
        uniq(find(u), find(*it));
        ancestor[find(u)] = u;
    }
    color[u] = true;
    for (itp = pairs[u].begin(); itp != pairs[u].end(); ++ itp)
        if (color[itp->first] == true)
            answers[itp->second] = ancestor[find(itp->first)];
}

int main(void) {
    ifstream in(iname);
    ofstream out(oname);
    int n, m;

    in >> n >> m;
    assert(1 <= n && n <= 100000);
    assert(1 <= m && m <= 2000000);
    for (int i = 2; i <= n; ++ i) {
        int node;
        in >> node,
        assert(1 <= node && node <= 100000);
        adj[node].push_back(i);
    }
    for (int i = 0; i < m; ++ i) {
        int x, y;
        in >> x >> y;
        assert(1 <= x && x <= 100000);
        assert(1 <= y && y <= 100000);
        pairs[x].push_back(make_pair(y, i));
        pairs[y].push_back(make_pair(x, i));
    }
    DF(1);
    for (int i = 0; i < m; ++ i)
        out << answers[i] << "\n";

    in.close();
    out.close();
    return 0;
}