Pagini recente » Cod sursa (job #199861) | Cod sursa (job #1264355) | Cod sursa (job #2863943) | Cod sursa (job #1094259) | Cod sursa (job #2466520)
#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;
}