Pagini recente » Istoria paginii utilizator/anime_lover | Cod sursa (job #8951) | Cod sursa (job #2204507) | Cod sursa (job #882889) | Cod sursa (job #2181858)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
int k = 2;
typedef struct nod{
int* copii;
int nCopii;
int k;
int nMaxCopii;
}TNod;
typedef struct {
int v, n;
}rmq;
void EulerianPath(int *Euler, int *nivel, TNod *noduri, int *adancime, int *primaAparitie, int x)
{
while(noduri[x].k < noduri[x].nCopii){
Euler[k] = noduri[x].copii[noduri[x].k];
nivel[k] = adancime[x]+1;
if(!primaAparitie[Euler[k]]) primaAparitie[Euler[k]] = k;
k++;
EulerianPath( Euler, nivel, noduri, adancime, primaAparitie, Euler[k-1]);
Euler[k] = x;
nivel[k] = adancime[x];
k++;
noduri[x].k++;
}
}
int main()
{
int n, m, x;
FILE *fi, *fo;
fi = fopen("lca.in", "r");
fscanf(fi,"%d %d", &n, &m);
TNod* noduri=(TNod*)malloc((n+1)*sizeof(TNod));
int N, i, j;
int* Euler =(int*)malloc((2*n+3)* sizeof(int));
int* nivel =(int*)malloc((2*n+3)* sizeof(int));
int* adancime = (int*)malloc((n+1)*sizeof(int));
int* primaAparitie = (int*)calloc((n+1),sizeof(int));
adancime[1] = 0;
for(i = 1; i <= n; i++)
{ noduri[i].nMaxCopii = 50;
noduri[i].copii=(int*)malloc(50*sizeof(int));
noduri[i].nCopii = 0;
noduri[i].k=0;
}
for(i = 2; i <= n; i++)
{
fscanf(fi,"%d",&x);
if(noduri[x].nCopii == noduri[x].nMaxCopii){
noduri[x].nMaxCopii*=2;
int* temp=(int*)realloc(noduri[x].copii, noduri[x].nMaxCopii*sizeof(int));
noduri[x].copii = temp;
temp = NULL;
}
noduri[x].copii[noduri[x].nCopii] = i;
noduri[x].nCopii++;
adancime[i] = adancime[x]+1;
}
Euler[1] = 1;
primaAparitie[1]=0;
nivel[1]=0;
EulerianPath(Euler, nivel, noduri, adancime, primaAparitie, 1);
N = k;
int lg = log2(N);
rmq** d=(rmq**)malloc((lg+1)*sizeof(rmq*));
for(i = 0; i < lg+1; i++)
{
d[i] =(rmq*)malloc((N+1)*sizeof(rmq));
}
for(j = 1; j <= N; j++)
{
d[0][j].v = nivel[j];
d[0][j].n = Euler[j];
}
int y = 1;
for( i = 1; i <= lg; i++ )
{
for(j = 1; j < 2*y; j++)
{
d[i][j].v = d[i-1][j].v;
d[i][j].n = d[i-1][j].n;
}
for(; j <= N; j++)
{
if(d[i-1][j].v < d[i-1][j - y].v)
{
d[i][j].v = d[i-1][j].v;
d[i][j].n = d[i-1][j].n;
}
else{
d[i][j].v = d[i-1][j - y].v;
d[i][j].n = d[i-1][j - y].n;
}
}
y*=2;
}
int* putere =(int *)malloc((N+2)*sizeof(int));
putere[1] = 0;
putere[0] = 0;
for( i = 2; i <= N; i++)
{
putere[i] = putere[i/2] + 1;
}
fo = fopen("lca.out", "w");
for(i = 0; i < m; i++)
{
int l , r;
fscanf(fi,"%d %d", &l, &r);
l = primaAparitie[l];
r = primaAparitie[r];
if(l>r) {
int aux = l;
l = r;
r = aux;
}
int len = r - l + 1;
int p = putere[len-1];
int valPutere = (1<<p);
if(d[p][r].v < d[p][l + valPutere - 1].v)
fprintf(fo,"%d\n", d[p][r].n);
else fprintf(fo,"%d\n", d[p][l + valPutere - 1].n);
}
free(putere);
for(i = 0; i < lg+1; i++)
free(d[i]);
free(d);
free(putere);
free(Euler);
free(adancime);
free(primaAparitie);
free(nivel);
for(i = 1; i <= n; i++){
free(noduri[i].copii);
}
free(noduri);
fclose(fi);
fclose(fo);
return 0;
}