Cod sursa(job #1043103)

Utilizator mvcl3Marian Iacob mvcl3 Data 28 noiembrie 2013 00:02:43
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 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 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();
    for(int i = 1; i <= N; ++i)
    {
        memset(Viz, 0, sizeof(Viz));
        k_go(i);
    }
    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;
}