Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

codingfarm

LCA(Lowest Common Ancestor) 본문

Algorithm & Data structure/이론

LCA(Lowest Common Ancestor)

scarecrow1992 2020. 9. 6. 16:05
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include<iostream>
#include<vector>
 
using namespace std;
 
vector<vector<int>> tree;    //tree[i] : i 번 노드가 가지는 자식들의 목록
vector<vector<int>> par;    //par[node][i] : node의 2^i 번째 부모의 번호, par[node][i] = par[par[node][i-1]][i-1]
vector<int> depths;            //depths[i] : i번째 노드의 깊이(root의 깊이는 0 이다)
 
void DFS(int node, int dep) {
    depths[node] = dep;
    int cDepth = 1;
    int tmp, i = 1;
    while (dep >= cDepth) {
        par[node][i] = par[par[node][i - 1]][i - 1];
        i++;
        cDepth *= 2;
    }
 
    for (int i = 0; i < tree[node].size(); i++) {
        DFS(tree[node][i], dep + 1);
    }
}
 
int LCA(int a, int b) {
    //a와 b를 같은 깊이가 되도록 한다.
    int low, deep;
    if (depths[a] < depths[b])
        low = a, deep = b;
    else
        low = b, deep = a;
 
    int diff = depths[deep] - depths[low];
 
    //deep의 위치를 diff만큼 끌어올려서 low와 같게한다.
    int i = 0;
    while (1) {
        if (diff == 0)
            break;
        if ((diff & 1!= 0)
            deep = par[deep][i];
 
        diff = diff >> 1;
        i++;
    }
 
    //low와 deep 번호의 최소 공통조상을 구한다.
    
    if (low == deep)
        return low;
    
    int index = 1;
    while (par[low][0!= par[deep][0]) {
        while (par[low][index] != par[deep][index])
            index++;
        index--;
        low = par[low][index];
        deep = par[deep][index];
    }
 
    return par[low][0];
}
 
 
int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int N;
    cin >> N;
 
    tree.assign(N, vector<int>());
    par.assign(N, vector<int>(N, -1));
    depths.assign(N, -1);
    int input;
 
    for (int i = 1; i < N; i++) {
        cin >> input;
        //i의 직계부모는 input이다.
        par[i][0= input;
        tree[input].push_back(i);
    }
 
    DFS(00);
    int ret = LCA(510);
    ret = LCA(113);
    ret = LCA(710);
    ret = LCA(136);
    ret = LCA(11);
    ret = LCA(227);
    ret = LCA(514);
 
    return 0;
}
 
 
/*
19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
31
0 0
1 1 2 2
3 3 4 4 5 5 6 6
7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14
*/
cs

'Algorithm & Data structure > 이론' 카테고리의 다른 글

BST(Binary Search Tree)  (0) 2020.09.06
Heap  (0) 2020.09.06
MST(Minimum Spanning Tree) & Kruskal  (0) 2020.09.06
Union Find  (0) 2020.09.06
Merge Sort  (0) 2020.09.06
Comments