Pagini recente » Cod sursa (job #3316045) | Cod sursa (job #3302287) | Cod sursa (job #3322916) | Cod sursa (job #3322922) | Cod sursa (job #3349138)
#include <stdio.h>
#define MAXN 100000
#define MAXQ 2000000
using namespace std;
FILE *fin, *fout;
struct cell{
int v, next;
};
struct node{
int adj;
int depth;
int time_in, time_out;
int parent;
int jump;
};
struct query{
int u, v;
};
cell edges[2*MAXN];
node nd[MAXN+1];
query queries[MAXQ];
int n, q;
void dfs(int u){
static int time=1;
nd[u].time_in=time++;
int u2=nd[u].jump, u3=nd[u2].jump;
bool egal=false;
if(nd[u2].depth-nd[u].depth==nd[u3].depth-nd[u2].depth){
egal=true;
}
for(int ptr=nd[u].adj;ptr;ptr=edges[ptr].next){
int v=edges[ptr].v;
if(!nd[v].depth){
nd[v].depth=nd[u].depth+1;
nd[v].parent=u;
if(egal){
nd[v].jump=u3;
}
else{
nd[v].jump=u;
}
dfs(v);
}
}
nd[u].time_out=time++;
}
bool is_ancestor(int u, int v){
return (nd[u].time_in<=nd[v].time_in)&&
(nd[u].time_out>=nd[v].time_out);
}
int lca(int u, int v){
while(!is_ancestor(u, v)){
if(nd[u].jump&&!is_ancestor(nd[u].jump, v)){
u=nd[u].jump;
}
else{
u=nd[u].parent;
}
}
return u;
}
void add_edge(int u, int v){
static int pos=1;
edges[pos]={v, nd[u].adj};
nd[u].adj=pos++;
}
void read_graph_and_queries(){
int u;
fin=fopen("lca.in", "r");
fscanf(fin, "%d%d", &n, &q);
for(int i=2;i<=n;i++){
fscanf(fin, "%d", &u);
add_edge(i, u);
add_edge(u, i);
}
for(int i=0;i<q;i++){
fscanf(fin, "%d%d", &queries[i].u, &queries[i].v);
}
fclose(fin);
}
void ans_queries(){
fout=fopen("lca.out", "w");
for(int i=0;i<q;i++){
fprintf(fout, "%d\n", lca(queries[i].u, queries[i].v));
}
fclose(fout);
}
int main()
{
read_graph_and_queries();
nd[1].depth=1;
dfs(1);
ans_queries();
return 0;
}