Pagini recente » Cod sursa (job #872772) | Cod sursa (job #713662) | Cod sursa (job #1238520) | Cod sursa (job #1318265) | Cod sursa (job #1043104)
#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 k_go(int node)
{
int rez = 0;
Viz[node] = 1;
for(auto val : V[node])
{
if(!Viz[val])
rez += k_go(val) + 1;
};
Kids[node] = rez;
return rez;
}
void l_go(int s, int d, int l, int r)
{
Viz[s] = 1;
Dist[s] = d;
Last[s] = l;
Turn[s] = r;
int maxval = 0;
int idx = -1;
for(auto val : V[s])
{
if(!Viz[val])
{
int k = Kids[val];
if(k > maxval)
{
maxval = k;
idx = val;
}
}
};
for(auto val : V[s])
{
if(!Viz[val])
{
if(idx == val)
l_go(val, d + 1, l, r);
else
l_go(val, d + 1, s, 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(a, Last[b]);
}
int main()
{
Read_Data();
k_go(1);
memset(Viz, 0, sizeof(Viz));
l_go(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;
}