Cod sursa(job #2445871)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 5 august 2019 20:33:46
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
//LCA cu Alg lui Tarjan-offline
#include<iostream>
#include<vector>
#include<fstream>
#define nmax 100000
using namespace std;

int n,m;
vector<int> G[nmax];
vector< pair<int,int> > query[nmax];
bool colour[nmax];
int ancestor[nmax],ans[nmax],tata[nmax],h[nmax];

void read()
{
    int x,y;
    ifstream fin("lca.in");
    fin>>n>>m;
    for(int i=2;i<=n;i++)
    {
        fin>>x;
        G[x].push_back(i);
    }
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y;
        query[x].push_back(make_pair(y,i));
        query[y].push_back(make_pair(x,i));
    }
    fin.close();

}

void makeSet(int x)
{
    tata[x]=x;
    h[x]=1;
}

int Find(int x)
{
    if(tata[x]!=x)
        tata[x]=Find(tata[x]);
    return tata[x];
    //pot aplica regula de compresie, deoarece am retinut radacina-eventualul raspuns la query-in ancestor
}

void Union(int x,int y)
{
    int xroot=Find(x),yroot=Find(y);
    if(h[xroot]==h[yroot])
    {
        tata[yroot]=xroot;
        h[xroot]++;

    }
    else
        (h[xroot]>h[yroot]) ? tata[yroot]=xroot : tata[xroot]=yroot;

}

void Tarjan(int u)
{
    makeSet(u);
    ancestor[Find(u)]=u;
    vector<int>::iterator it;
    for(it=G[u].begin();it!=G[u].end();it++)
    {
        Tarjan(*it);
        Union(u,*it);
        ancestor[Find(u)]=u;
    }
    colour[u]=true;
    vector< pair <int,int> >::iterator IT;
    for(IT=query[u].begin();IT!=query[u].end();IT++)
    {
        if(colour[(*IT).first]=true)
            ans[(*IT).second]=ancestor[Find((*IT).first)];
    }

}



int main()
{
    read();
    Tarjan(1);
    ofstream fout("lca.out");
    for(int i=1;i<=m;i++)
        fout<<ans[i]<<'\n';
    fout.close();
}