Cod sursa(job #2091490)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 19 decembrie 2017 19:04:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 kb
//lacusta-oji, 2005
/*#include<bits/stdc++.h>
#define oo 32000
#define Dim 252
using namespace std;
int main()
{   int i,j,jmin,min1,min2,ans,n,m,b[Dim][Dim];
short int a[Dim][Dim];
    freopen("lacusta.in","r",stdin);
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
        scanf("%d",&a[i][j]);

    b[0][0]=(int)a[0][0];
    b[1][0]=oo;
    for(i=1;i<n;i++)
        b[1][i]=(int)a[0][0]+(int)a[0][i]+(int)a[1][i];
    for(i=1;i<m-1;i++)
    {
        if(b[i%2][0]<=b[i%2][1])
        {
            min1=b[i%2][0];
            min2=b[i%2][1];
            jmin=0;
        }
        else
            {jmin=1;
        min1=b[i%2][1];
        min2=b[i%2][0];
            }

        for(j=2;j<n;j++)
            if(b[i%2][j]<min1)
        {
            min2=min1;
            min1=b[i%2][j];
            jmin=j;
        }
        else
            if(b[i%2][j]<min2)
            min2=b[i%2][j];

        for(j=0;j<n;j++)
            if(j!=jmin) b[(i+1)%2][j]=(int)(min1+a[i][j]+a[i+1][j]);
              else b[(i+1)%2][j]=(int)(min2+a[i][j]+a[i+1][j]);

    }
    ans=b[(m-1)%2][0];
    for(j=1;j<n;j++)
        if(ans>b[(m-1)%2][j]) ans=b[(m-1)%2][j];
    freopen("lacusta.out","w",stdout);
    cout<<(ans+a[m-1][n-1]);
    //cout<<double(clock()-start)/double(CLOCKS_PER_SEC);
    return 0;
}*/

//LCA-met1 si 2


/*#include<bits/stdc++.h>
#define N 100004
using namespace std;
int n,m,T[N],R[N],T2[N],Lev[N],H,ad=-N;

void dfs(int nod, int dist)
{   int i;
    R[nod]=dist;
    if(dist>ad) ad=dist;
    for(i=1;i<=n;i++)
        if(T[i]==nod)
        dfs(i,dist+1);
}


void dfs2(int nod, int t2,int lev)
{
    int i;
    T2[nod]=t2;
    Lev[nod]=lev;
    if(!lev%H) t2=nod;
    for(i=1;i<=n;i++)
        if(T[i]==nod) dfs2(i,t2,lev+1);
}

int LCA(int x,int y)
{
    while(T2[x]!=T2[y])
    {
        if(Lev[x]>Lev[y]) x=T2[x];
        else y=T2[y];
    }
    while(x!=y)
    {
        if(Lev[x]>Lev[y]) x=T[x];
        else y=T[y];
    }
    return x;
}

int main()
{
     freopen("lca.in","r",stdin);
    freopen("lca.out","wt",stdout);

    scanf("%d %d\n", &n, &m);

     int i;
    for(i=2;i<=n;++i) scanf("%d ",&T[i]);

    //dfs(1,0);
    //sort(R+1,R+n+1);
    //H=R[n];
    //H=9;
    H=sqrt(n));

   // for(i=1;i<=m;i++)
   // {
   //     int x,y;
   //     scanf("%d %d\n",&x,&y);
   //     while(x!=y)
   //         if(R[x]>R[y]) x=T[x];
    //          else y=T[y];
//
   //     printf("%d\n",y);
   // }

    dfs2(1,0,0);
for(i=1;i<=m;i++)
{
    int x,y;
    scanf("%d %d\n",&x,&y);
    printf("%d\n",LCA(x,y));
}
*/

#include <bits/stdc++.h>
using namespace std;
const int Nmax = 100000 + 2;
vector <int> G[Nmax];
int depth[Nmax];
int tata[Nmax];
int group[Nmax];
int N, M, H, SQRT;
void DFS( int nod, int d, int gr )
{
    depth[nod] = d;
    group[nod] = gr;

    if ( d % SQRT == 0 ) gr=nod;

    for (int j=0;j<G[nod].size();j++)
    {  int x=G[nod][j];
        if ( tata[x] == 0 )
        {
            tata[x] = nod;
            DFS( x, d + 1, gr );
        }
    }
}

int lca( int x, int y )
{
    while ( group[x] != group[y] )
    {
        if ( depth[x] > depth[y] )
                x = group[x];
        else
                y = group[y];
    }

    while ( x != y )
    {
        if ( depth[x] > depth[y] )
                x = tata[x];
        else
                y = tata[y];
    }

    return x;
}

int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");

    f >> N >> M;

    for ( int i = 2, a; i <= N; ++i )
    {
        f >> a;
        G[a].push_back(i);
    }

    SQRT = sqrt(N);

    DFS( 1, 0, 1 );

    for ( int i = 1, a, b; i <= M; ++i )
    {
        f >> a >> b;
        g << lca( a, b ) << "\n";
    }

    return 0;
}