Cod sursa(job #1992826)

Utilizator preda.andreiPreda Andrei preda.andrei Data 21 iunie 2017 15:30:22
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

struct Node
{
    int exit_time;
    vector<int> ancestors;
    vector<int> sons;
};

using Tree = vector<Node>;

void Dfs(Tree &t, int node, vector<int> &st, int level = 0)
{
    static int time = 0;
    st[level] = node;

    if (level > 0) {
        int ancestor = t[node].ancestors.front();
        int power = 1;

        while ((1 << power) <= level) {
            t[node].ancestors.push_back(t[ancestor].ancestors[power - 1]);
            ++power;
        }
    }

    for (int son : t[node].sons) {
        Dfs(t, son, st, level + 1);
    }

    t[node].exit_time = ++time;
}

int FindLca(const Tree &t, int x, int y)
{
    if (t[x].exit_time > t[y].exit_time) {
        swap(x, y);
    }

    while (x != 0 && t[x].exit_time < t[y].exit_time) {
        int power = 0;
        int next_power = 0;
        while (power < (int)t[x].ancestors.size()) {
            int next_x = t[x].ancestors[power];
            if (t[next_x].exit_time <= t[y].exit_time) {
                next_power = power;
                ++power;
            } else {
                break;
            }
        }
        x = t[x].ancestors[next_power];
    }
    return x;
}

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

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

    Tree tree(n);
    for (int i = 1; i < n; ++i) {
        int father;
        fin >> father;
        tree[i].ancestors.push_back(father - 1);
        tree[father - 1].sons.push_back(i);
    }

    vector<int> st(n);
    Dfs(tree, 0, st);

    stringstream output;
    while (m--) {
        int x, y;
        fin >> x >> y;
        output << FindLca(tree, x - 1, y - 1) + 1 << "\n";
    }

    fout << output.str();
    return 0;
}