일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- DP
- 스토어드 프로시저
- SQL
- 그래프
- Brute Force
- Trie
- Dijkstra
- 이진탐색
- binary search
- 다익스트라
- Two Points
- two pointer
- Stored Procedure
- MYSQL
- Hash
- String
- union find
Archives
- Today
- Total
codingfarm
LCA(Lowest Common Ancestor) 본문
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(0, 0); int ret = LCA(5, 10); ret = LCA(1, 13); ret = LCA(7, 10); ret = LCA(13, 6); ret = LCA(1, 1); ret = LCA(2, 27); ret = LCA(5, 14); 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