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 107 108 109 110 111 112 113 114 115 116 117 | #include <stdio.h> #include <vector> #include <math.h> using namespace std; int depth[50005] = { 0 }; int par[50005][30] = { 0 }; int visit[50005] = { 0 }; int rst; vector<vector<int> > son(50005); vector<vector<int> > adj(50005); void dfs(int idx); void lca(int idx1, int idx2); void generate(int idx); int main() { int n, m; scanf("%d", &n); getchar(); depth[1] = 1; for (int i = 0; i < n - 1; i++) { int a, b; scanf("%d %d", &a, &b); getchar(); adj[a].push_back(b); adj[b].push_back(a); } generate(1); scanf("%d", &m); while (m--) { int a, b; scanf("%d %d", &a, &b); lca(a, b); printf("%d\n", rst); } } void generate(int idx) { visit[idx] = 1; for (int i = 0; i < adj[idx].size(); i++) { int x = adj[idx][i]; if (visit[x] == 0) { depth[x] = depth[idx] + 1; par[x][0] = idx; son[idx].push_back(x); for (int j = 1;; j++) { if (par[par[x][j-1]][j-1] != 0) { par[x][j] = par[par[x][j - 1]][j - 1]; } else break; } generate(x); } } } void lca(int idx1, int idx2) { //높이 똑같이 맞춰주는 부분 if (depth[idx1] < depth[idx2]) { //swap int tmp = idx2; idx2 = idx1; idx1 = tmp; } int len = depth[idx1] - depth[idx2], iter; if (len != 0) { iter = (int)log2(len); idx1 = par[idx1][iter]; } else iter = 0; while (depth[idx1] != depth[idx2]) { idx1 = par[idx1][0]; } //둘중 하나가 조상일때 - lca를 멈춤 if (idx1 == idx2) { rst = idx1; return; } //공통조상 찾는 부분 int i; for (i = 0; ; i++) { if (par[idx1][i] == par[idx2][i]) { break; } } if (i != 0) { idx1 = par[idx1][i - 1]; idx2 = par[idx2][i - 1]; } while (idx1 != idx2) { idx1 = par[idx1][0]; idx2 = par[idx2][0]; } //결괏값 저장 rst = idx1; } | cs |
'알고리즘 > DFS' 카테고리의 다른 글
2798 블랙잭 (0) | 2019.09.15 |
---|---|
11438 LCA2 (0) | 2019.09.15 |
10451 순열 사이클 (0) | 2019.09.04 |
9466 텀 프로젝트(hard) (0) | 2019.09.03 |
2668 숫자 고르기 (0) | 2019.09.03 |