Pagini recente » Cod sursa (job #233509) | Cod sursa (job #2232255) | Cod sursa (job #963658) | Cod sursa (job #464715) | Cod sursa (job #1989826)
#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;
}