https://www.acmicpc.net/problem/11438
이 기초다.
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
|
#include <iostream>
#include <vector>
#include <algorithm>
#define pii pair<int, int>
using namespace std;
int n;
vector<int> edge[100001];
int LCA[100001][18] = { 0 };
int depth[100001];
void go(int cur, int parent, int d)
{
LCA[cur][0] = parent;
depth[cur] = d;
for (int i = 1; i < 18; i++)
{
LCA[cur][i] = LCA[LCA[cur][i - 1]][i - 1];
}
for (int i = 0; i < edge[cur].size(); i++)
{
if (edge[cur][i] == parent)
continue;
go(edge[cur][i], cur, d+1);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
int a, b;
for (int i = 0; i < n-1; i++)
{
cin >> a >> b;
edge[a].push_back(b);
edge[b].push_back(a);
}
go(1, 0, 1);
/*
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < 18; j++)
cout << LCA[i][j] << ' ';
cout << '\n';
}
*/
int m;
cin >> m;
for (int i = 0; i < m; i++)
{
cin >> a >> b;
if (depth[a] > depth[b])
swap(a, b); // b가 무조건 더 깊다.
for (int i = 17; i >= 0; i--)
{
if (depth[LCA[b][i]] >= depth[a]) // 깊이 같게 맞춰주기.
b = LCA[b][i];
}
if (a == b)
cout << b << '\n';
else
{
for (int i = 17; i >= 0; i--)
{
int aa = LCA[a][i];
int bb = LCA[b][i];
if (aa == bb)
continue;
a = aa;
b = bb;
}
cout << LCA[a][0] << '\n';
}
}
}
|
cs |
그리고 밑에는 STL 없애고 푼것이다.
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #include <iostream> using namespace std; int n; int LCA[100001][18] = { 0 }; int depth[100001]; class node { public : int data; node* next; }; class Edge { public : node* head = NULL; node* tail = NULL; void insert(int d) { node* nnode = new node; nnode->data = d; nnode->next = NULL; if (head == NULL) head = nnode; else tail->next = nnode; tail = nnode; } }; Edge edge[100001]; void go(int cur, int parent, int d) { LCA[cur][0] = parent; depth[cur] = d; for (int i = 1; i < 18; i++) { LCA[cur][i] = LCA[LCA[cur][i - 1]][i - 1]; } node* tmp = edge[cur].head; while (tmp != NULL) { if (tmp->data != parent) go(tmp->data, cur, d + 1); tmp = tmp->next; } /* for (int i = 0; i < edge[cur].size(); i++) { if (edge[cur][i] == parent) continue; go(edge[cur][i], cur, d + 1); } */ } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n; int a, b; for (int i = 0; i < n - 1; i++) { cin >> a >> b; edge[a].insert(b); edge[b].insert(a); } go(1, 0, 1); /* for (int i = 1; i <= n; i++) { for (int j = 0; j < 18; j++) cout << LCA[i][j] << ' '; cout << '\n'; } */ int m; cin >> m; for (int i = 0; i < m; i++) { cin >> a >> b; if (depth[a] > depth[b]) swap(a, b); // b가 무조건 더 깊다. for (int i = 17; i >= 0; i--) { if (depth[LCA[b][i]] >= depth[a]) // 깊이 같게 맞춰주기. b = LCA[b][i]; } if (a == b) cout << b << '\n'; else { for (int i = 17; i >= 0; i--) { int aa = LCA[a][i]; int bb = LCA[b][i]; if (aa == bb) continue; a = aa; b = bb; } cout << LCA[a][0] << '\n'; } } } | cs |
'알고리즘 기술' 카테고리의 다른 글
[DP] LIS, LCS, MCM (0) | 2021.04.09 |
---|---|
[DP] TSP(외판원 순회) (0) | 2021.04.08 |
위상정렬 Feat DFS, BFS (0) | 2020.08.20 |
Trie와 동적 Trie (0) | 2020.08.19 |
KMP (0) | 2020.07.17 |