Cod sursa(job #2466520)

Utilizator paul_danutDandelion paul_danut Data 2 octombrie 2019 14:42:18
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include <vector>
#include <set>
#include <iostream>

int getAncestorOnLevel(std::vector<int> parents, const std::vector<int> levels, int node, int level)
{
    while(levels[node-1] != level)
    {
        node = parents[node-1];
    }

    return node;
}

int findLCA(const std::vector<int>& parents, const std::vector<int> levels, int x, int y, int root)
{
    auto minLevel = std::min(levels[x-1], levels[y-1]);
    x = getAncestorOnLevel(parents, levels, x, minLevel);
    y = getAncestorOnLevel(parents, levels, y, minLevel);

    std::set<int> visited;
    while(true)
    {
        if(x != -1)
        {
            const auto res = visited.insert(x);
            if(!res.second)
                return *res.first;
            x = parents[x-1];
        }
        if(y != -1)
        {
            const auto res = visited.insert(y);
            if(!res.second)
                return *res.first;
            y = parents[y-1];
        }
    }
}

std::vector<int> computeLevels(const std::vector<int> &parents, int root)
{
    std::vector<int> levels;
    for(auto i=0; i < parents.size(); ++i)
    {
        auto node = i+1;
        auto level = 1;
        while(node != root)
        {
            node = parents[node-1];
            ++level;
        }
        levels.push_back(level);
    }

    return levels;
}

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

    auto n=0, m=0, x=0, y=0, root = 1;
    fin>>n>>m;

    std::vector<int> parents;
    parents.push_back(-1); // primul nod este nodul radacina
    for(auto i=0; i < n-1; ++i)
    {
        fin>>x;
        parents.push_back(x);
    }
    auto levels = computeLevels(parents, root);

    for(auto i=0; i < m; ++i)
    {
        fin >> x >> y;
        fout << findLCA(parents, levels, x, y, root) << '\n';
    }

    return 0;
}