六、完善程序2

、(最近公共祖先)已知一棵有根的多叉树,每次询问下求给定的两个点的最近公共祖先。其中输入的第一行 3 个整数为结点个数,询问次数,根节点序号。祖先结点:指一个结点本身或者它父节点的祖先。最近公共祖先:在一棵有根树中,对于任意两个结点的公共祖先中距离两者最近的结点。

 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
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 500010;
vector<int> edge[MAXN];
int depth[MAXN], lg[MAXN];
int pa[MAXN][22];
int n, m, r, x, y;

void dfs(int fa, int sn, int dep) {
    depth[sn] = dep;
    pa[sn][0] = fa;
    for(int i = 1;  ; i++) {
        pa[sn][i] = pa[pa[sn][i - 1]][i - 1];
    }
    for(int i = 0; i < edge[sn].size(); i++) {
        int fn = edge[sn][i];
        if (fn == fa) {
        continue;
        }
    dfs(  );
    }
}

int solve(int x, int y) {
    if (depth[x] < depth[y]) {
        swap(x, y);
    }
    while(depth[x] > depth[y]) {
    x =  ;
    } 
    if(x == y) {
        return x;
    }
    for(int k = lg[depth[x]] - 1; k >= 0; --k) {
        if(  ) {
        x = pa[x][k], y = pa[y][k];
        }
    } 
return pa[x][0];
}
int main() {
    cin >> n >> m >> r;
    for(int i = 1; i <= n; i++)
        lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    for (int i = 0; i < n - 1; i++) {
        cin >> x >> y;
        edge[x].push_back(y);
        edge[y].push_back(x);
}
    dfs(  );
    while (m--) {
        cin >> x >> y;
        cout << solve(x, y) << endl;
    }
return 0;
}
Scroll to Top