Cod sursa(job #1989826)

Utilizator Tester100Tester Tester100 Data 9 iunie 2017 00:40:25
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <fstream>
#include <tuple>
#include <vector>
#include <algorithm>
#include <cassert>
#include <iostream>

class LowestCommonAncestorSolver
{
    public: 
    LowestCommonAncestorSolver(const std::vector< std::vector < int > > &tree,const int &root)
    {
        n = tree.size();
        
        int step;
        for(step = 0; (1 << step) <= n; ++step);

        father = std::vector < std :: vector < int > >(step , std::vector < int > (n, 0));
        level = std::vector < int > (n, -1);
        level[root] = 0;
        Dfs(tree,root, father[0]);

        for(int i = 1; (1 << i) <= n; ++i)
            for(int j = 0; j < n; ++j)
                father[i][j] = father[i-1][father[i-1][j]];
    }  
    int GetLowestCommonAncestor(int x, int y)
    {
        assert(0 <=x && x < n);
        assert(0 <=y && y < n);
        if(level[x] < level[y])
            std::swap(x, y);
        int step;
        for(step = 0; (1 << step) <= n; ++step);
        step--;
        for(int i = step; i >= 0; --i)
            if(level[father[i][x]] >= level[y])
                x = father[i][x];
        if(x == y)
            return x;
        for(int i = step; i >= 0; --i)
            if(father[i][x] != father[i][y])
                x = father[i][x], y = father[i][y];
        return father[0][x];
    }
    private:

    void Dfs(const std::vector < std::vector < int > > &tree,const int &root, std::vector < int > &father)
    {
        for(auto x : tree[root])
        {
            if(level[x] == -1)
            {
                level[x] = level[root] + 1;
                father[x] = root;
                Dfs(tree, x, father);
            }
        }
    }
    int n;
    std::vector < std::vector < int > > father;
    std::vector < int > level;
};

std::tuple < std::vector< std::vector < int > >, int , std::vector < std::pair < int ,int > > >  Read(const char *file)
{
    int n, m;
    std::ifstream in(file);
    in >> n >> m;    
    
    int root = 0;
    std::vector < std::vector < int > > tree(n,  std::vector < int >());
    std::vector < std::pair < int , int > > queries(m); 

    for (int son = 1; son < n; son++)
    {
        int father;
        in >> father;
        father--;
        tree[father].push_back(son);
    }
    for(auto &query: queries)
    {
        in >> query.first >> query.second;
        query.first--, query.second--;
    }
    in.close();
    return std::make_tuple(tree, root,queries);
}

std::vector < int > Solve(const std::tuple < std::vector< std::vector < int > >, int , std::vector < std::pair < int ,int > > > &tup)
{
    std::vector < std::vector < int > > tree;
    int root;
    std::vector < std::pair < int, int > > queries;
    std::tie(tree,root,queries) = tup;
    LowestCommonAncestorSolver helper(tree,root);
    std::vector < int > answers;
    for(auto query : queries)
    {
        answers.push_back(helper.GetLowestCommonAncestor(query.first,query.second));
    }
    return answers;
}

void Write(std::vector < int > answers,const char *file)
{
    std::ofstream out(file);
    for(auto x : answers)
        out << x + 1<< "\n";
    out.close();
}

int main()
{
    Write(Solve(Read("lca.in")),"lca.out");
    return 0;
}