Cod sursa(job #2955976)

Utilizator matthriscuMatt . matthriscu Data 18 decembrie 2022 13:40:47
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
// #include "dsu.hpp"

class DSU {
private:
	std::vector<int> rank, rep;
public:
	DSU(int n);
	int find_rep(int x);
    void unite(int x, int y);
	bool check(int x, int y);
};

int DSU::find_rep(int x) {
    if (rep[x] == x)
        return x;
    return rep[x] = find_rep(rep[x]);
}

DSU::DSU(int n) : rank(n + 1), rep(n + 1) {
    for (int i = 1; i <= n; ++i)
        rep[i] = i;
}

void DSU::unite(int x, int y) {
    int rep_x = find_rep(x), rep_y = find_rep(y);

    if (rank[rep_x] < rank[rep_y]) {
        ++rank[rep_y];
        rep[rep_x] = rep_y;
    } else {
        ++rank[rep_y];
        rep[rep_x] = rep_y;
    }
}

bool DSU::check(int x, int y) {
    return find_rep(x) == find_rep(y);
}

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';
    }
}