Skip to content

Commit 9ec1c2e

Browse files
authored
倍增法求最近公共祖先
1 parent 51540fe commit 9ec1c2e

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

Lowest-Common-Ancestor(Doubling).cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include <cstdio>
2+
3+
using namespace std;
4+
5+
struct vertex
6+
{
7+
int first, depth;
8+
}V[100010];
9+
10+
struct edge
11+
{
12+
int endp, next;
13+
}E[200010];
14+
15+
int ec = 1, ivc;
16+
int fa[100010][25];
17+
18+
void add_edge(int u, int v)
19+
{
20+
E[ec].next = V[u].first;
21+
V[u].first = ec;
22+
E[ec].endp = v;
23+
ec++;
24+
}
25+
26+
void DFS(int u, int prev, int depth)
27+
{
28+
if (fa[u][0] == 0)
29+
{
30+
fa[u][0] = prev;
31+
V[u].depth = depth;
32+
for (int cur = V[u].first; cur != 0; cur = E[cur].next)
33+
{
34+
DFS(E[cur].endp, u, depth + 1);
35+
}
36+
}
37+
}
38+
39+
void init()
40+
{
41+
DFS(1, -1, 1);
42+
for (int i = 1; i <= 20; i++)
43+
{
44+
for (int j = 1; j <= ivc; j++)
45+
{
46+
fa[j][i] = fa[fa[j][i - 1]][i - 1];
47+
}
48+
}
49+
}
50+
51+
int lca(int a, int b)
52+
{
53+
if (V[b].depth > V[a].depth)
54+
{
55+
int temp = a;
56+
a = b;
57+
b = temp;
58+
}
59+
int delta = V[a].depth - V[b].depth, k = 0;
60+
while (delta > 0)
61+
{
62+
if ((delta & 1) == 1)
63+
{
64+
a = fa[a][k];
65+
}
66+
k++;
67+
delta >>= 1;
68+
}
69+
if (a == b)
70+
{
71+
return a;
72+
}
73+
for (int i = 20; i >= 0; i--)
74+
{
75+
if (fa[a][i] != fa[b][i])
76+
{
77+
a = fa[a][i];
78+
b = fa[b][i];
79+
}
80+
}
81+
return fa[a][0];
82+
}
83+
84+
int main()
85+
{
86+
int u, v;
87+
scanf("%d", &ivc);
88+
for (int i = 1; i < ivc; i++)
89+
{
90+
scanf("%d%d", &u, &v);
91+
add_edge(u, v);
92+
add_edge(v, u);
93+
}
94+
init();
95+
while (true)
96+
{
97+
scanf("%d%d", &u, &v);
98+
printf("%d\n", lca(u, v));
99+
}
100+
return 0;
101+
}

0 commit comments

Comments
 (0)