Cod sursa(job #2562088)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 29 februarie 2020 12:08:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
//  Offline LCA: see Competitive Programming Handbook (thx Codeforces!)

#include <bits/stdc++.h>

#define MAXN    100005
#define MAXM    2000005

int N, M;
std::vector <int> ADC[MAXN];
inline void addEdge(int u, int v) {
    ADC[u].push_back(v);
    ADC[v].push_back(u);
}
int ans[MAXM];
std::vector <std::pair <int, int>> paired[MAXN];
inline void pair(int u, int v, int idx) {
    paired[u].push_back({v, idx});
    paired[v].push_back({u, idx});
}

int high[MAXN];
int parent[MAXN], rang[MAXN];
int _find(int x) {
    if (x == parent[x]) return x;
    return parent[x] = _find(parent[x]);
}
void _union(int x, int y) {
    if (x == y) return;
    if (rang[x] > rang[y])  parent[y] = x;
    else                    parent[x] = y;
    if (rang[x] == rang[y]) ++ rang[y];
}

bool seen[MAXN];
void DFS(int vertex = 1, int parent = 0) {
    seen[vertex] = true;
    for (auto &it:ADC[vertex]) {
        if (it == parent) continue;
        DFS(it, vertex);
        high[_find(it)] = high[_find(vertex)];
        _union(_find(vertex), _find(it));
    }

    for (auto &it:paired[vertex]) {
        if (ans[it.second]) continue;
        if (!seen[it.first]) continue;
        ans[it.second] = high[_find(it.first)];
    }
}

std::ifstream input ("lca.in");
std::ofstream output("lca.out");

int main()
{
    input >> N >> M;
    for (int i=2, u; i<=N; ++i)    input >> u,      addEdge(i, u);
    for (int i=1, u, v; i<=M; ++i) input >> u >> v, pair(u, v, i);
    for (int i=1; i<=N; ++i) parent[i] = i, high[i] = i;
    DFS();
    for (int i=1; i<=M; ++i) output << ans[i] << '\n';

    return 0;
}