File tree 1 file changed +77
-0
lines changed
1 file changed +77
-0
lines changed Original file line number Diff line number Diff line change
1
+ // author : Avishkar A. Hande
2
+ #include < bits/stdc++.h>
3
+ #define ll long long
4
+ using namespace std ;
5
+
6
+ const int maxS = 1e5 +10 ;
7
+ vector<ll> adj[maxS];
8
+
9
+ ll LOG;
10
+ int timer;
11
+ vector<int > tin, tout;
12
+ vector<vector<int >> up;
13
+
14
+ /*
15
+ Binary Lifting is mostly used to find Lowest Common Ancestor
16
+ as it reduces the time complexity to log(n);
17
+ */
18
+
19
+ void dfs (int v, int p)
20
+ {
21
+ tin[v] = ++timer;
22
+ up[v][0 ] = p;
23
+ for (int i = 1 ; i <= LOG; ++i)
24
+ up[v][i] = up[up[v][i-1 ]][i-1 ];
25
+
26
+ for (int u : adj[v]) {
27
+ if (u != p)
28
+ dfs (u, v);
29
+ }
30
+
31
+ tout[v] = ++timer;
32
+ }
33
+
34
+ bool is_ancestor (int u, int v)
35
+ {
36
+ return tin[u] <= tin[v] && tout[u] >= tout[v];
37
+ }
38
+
39
+ int lca (int u, int v)
40
+ {
41
+ if (is_ancestor (u, v))
42
+ return u;
43
+ if (is_ancestor (v, u))
44
+ return v;
45
+ for (int i = LOG; i >= 0 ; --i) {
46
+ if (!is_ancestor (up[u][i], v))
47
+ u = up[u][i];
48
+ }
49
+ return up[u][0 ];
50
+ }
51
+
52
+ void preprocess (int root, int n) {
53
+ tin.resize (n);
54
+ tout.resize (n);
55
+ timer = 0 ;
56
+ LOG = ceil (log2 (n)) + 1 ;
57
+ up.assign (n+1 , vector<int >(LOG + 1 ));
58
+ dfs (root, root);
59
+ }
60
+
61
+ int main ()
62
+ {
63
+ ll node, queries;
64
+ cin >> node >> queries;
65
+ for (int i = 0 ; i < node-1 ; i++){
66
+ ll u, v;
67
+ cin >> u >> v;
68
+ adj[u].push_back (v);
69
+ adj[v].push_back (u);
70
+ }
71
+ preprocess (1 , node);
72
+ while (queries--){
73
+ ll a, b;
74
+ cin >> a >> b;
75
+ cout << lca (a, b) << endl;
76
+ }
77
+ }
You can’t perform that action at this time.
0 commit comments