Cod sursa(job #2955975)

Utilizator matthriscuMatt . matthriscu Data 18 decembrie 2022 13:39:44
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>
#include "dsu.hpp"
using namespace std;

vector<int> tarjan_offline(const vector<vector<int>>& tree,
                           const vector<vector<pair<int, int>>>& queries) {
    DSU dsu(tree.size());
    vector<bool> visited(tree.size(), false);
    vector<int> ancestor(tree.size());
    vector<int> ans(transform_reduce(queries.begin(), queries.end(), 0, plus{},
                                     size<decltype(queries[0])>) / 2);

    function<void(int)> dfs = [&](int current) {
        visited[current] = true;
        ancestor[current] = current;

        for (int neigh : tree[current])
            if (!visited[neigh]) {
                dfs(neigh);
                dsu.unite(current, neigh);
                ancestor[dsu.find_rep(current)] = current;
            }

        for (auto [other_node, index] : queries[current])
            if (visited[other_node]) {
                ans[index] = ancestor[dsu.find_rep(other_node)];
            }
    };

    dfs(0);

    return ans;
}

int main() {
    ifstream fin("lca.in");
    ofstream fout("lca.out");

    int n, m;
    fin >> n >> m;

    vector<vector<int>> tree(n);
    for (int i = 1, x; i < n; ++i) {
        fin >> x;
        --x;

        tree[i].push_back(x);
        tree[x].push_back(i);
    }

    vector<vector<pair<int, int>>> queries(n);
    for (int i = 0, x, y; i < m; ++i) {
        fin >> x >> y;
        --x;
        --y;
        queries[x].push_back({y, i});
        queries[y].push_back({x, i});
    }

    for (int x : tarjan_offline(tree, queries)) {
        fout << ++x << '\n';
    }
}