forked from beet-aizu/library
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlowestcommonancestor.cpp
87 lines (81 loc) · 1.5 KB
/
lowestcommonancestor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
//BEGIN CUT HERE
struct LowestCommonAncestor{
int n,h;
vector<vector<int> > G,par;
vector<int> dep;
LowestCommonAncestor(){}
LowestCommonAncestor(int n):n(n),G(n),dep(n){
h=1;
while((1<<h)<=n) h++;
par.assign(h,vector<int>(n,-1));
}
void add_edge(int u,int v){
G[u].emplace_back(v);
G[v].emplace_back(u);
}
void dfs(int v,int p,int d){
par[0][v]=p;
dep[v]=d;
for(int u:G[v])
if(u!=p) dfs(u,v,d+1);
}
void build(int r=0){
dfs(r,-1,0);
for(int k=0;k+1<h;k++){
for(int v=0;v<n;v++){
if(par[k][v]<0) par[k+1][v]=-1;
else par[k+1][v]=par[k][par[k][v]];
}
}
}
int lca(int u,int v){
if(dep[u]>dep[v]) swap(u,v);
for(int k=0;k<h;k++){
if((dep[v]-dep[u])>>k&1){
v=par[k][v];
}
}
if(u==v) return u;
for(int k=h-1;k>=0;k--){
if(par[k][u]!=par[k][v]){
u=par[k][u];
v=par[k][v];
}
}
return par[0][u];
}
int distance(int u,int v){
return dep[u]+dep[v]-dep[lca(u,v)]*2;
}
};
//END CUT HERE
signed main(){
int n;
cin>>n;
LowestCommonAncestor lca(n);
for(int i=0;i<n;i++){
int k;
cin>>k;
for(int j=0;j<k;j++){
int c;
cin>>c;
lca.add_edge(i,c);
}
}
lca.build();
int q;
cin>>q;
while(q--){
int u,v;
cin>>u>>v;
cout<<lca.lca(u,v)<<endl;
}
return 0;
}
/*
verified on 2018/05/16
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C&lang=jp
*/