Pagini recente » Cod sursa (job #708647) | Cod sursa (job #1022754) | Cod sursa (job #2452897) | Autentificare | Cod sursa (job #1043379)
#include <fstream>
#include <vector>
#include <string.h>
#define in "lca.in"
#define out "lca.out"
#define Max_Size 100009
std :: ifstream f(in);
std :: ofstream g(out);
int N, M;
std :: vector < int > V[Max_Size];
bool Viz[Max_Size]; //Vector care imi arata daca am vizitat sau nu nodul
int Dist[Max_Size]; //Distanta de la nod la radacina
int Kids[Max_Size]; //Numarul de copii pe care il are nodul
int Last[Max_Size]; //Tatal nodului
int Turn[Max_Size];
inline void Read_Data()
{
f >> N >> M;
for(int x, i = 1; i < N; ++i)
{
f >> x;
V[x].push_back(i + 1);
}
}
int Count_Kids(int node)
{
int rez = 0;
Viz[node] = 1;
for(auto val : V[node])
{
if(!Viz[val])
rez += Count_Kids(val) + 1;
};
Kids[node] = rez;
return rez;
}
void Solve(int node, int distance, int father, int r)
{
Viz[node] = 1;
Dist[node] = distance;
Last[node] = father;
Turn[node] = r;
int maxval = 0;
int idx = -1;
for(auto val : V[node])
{
if(!Viz[val])
{
int k = Kids[val];
if(k > maxval)
{
maxval = k;
idx = val;
}
}
};
for(auto val : V[node])
{
if(!Viz[val])
{
if(idx == val)
Solve(val, distance + 1, father, r);
else
Solve(val, distance + 1, node, val);
}
}
}
int LCA(int a, int b)
{
if(Turn[a] == Turn[b])
{
if(Dist[a] < Dist[b]) return a;
return b;
}
if(Dist[Last[a]] > Dist[Last[b]]) return LCA(Last[a], b);
return LCA(Last[b], a);
}
int main()
{
Read_Data();
Count_Kids(1);
memset(Viz, 0, sizeof(Viz));
Solve(1, 1, 1, 1);
for(int x, y, i = 1; i <= M; ++i)
{
f >> x >> y;
g << LCA(x, y) << '\n';
}
g.close();
return 0;
}