Cod sursa(job #1043379)

Utilizator mvcl3Marian Iacob mvcl3 Data 28 noiembrie 2013 15:03:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#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;
}