-
Notifications
You must be signed in to change notification settings - Fork 0
/
11437_LCA_lcrs_fail.cpp
153 lines (123 loc) · 2.12 KB
/
11437_LCA_lcrs_fail.cpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <iostream>
#include <stdio.h>
//lcrs트리로 구현해보자.
typedef struct Node
{
int id;
Node* childs;
Node* siblings;
}node;
typedef struct Data
{
node nodes[50010];
int idx;
node* idToptr[50010];
int pId[50010];
int depth[50010];
}data;
static data workspace;
inline node* getNewNode()
{
return &(workspace.nodes[workspace.idx++]);
}
void dfs(int pid, node* ptr, int depth)
{
//필요한 정보는 자기자신의 pid와 depth정보다.
//깊이 우선으로 돌며 각 id별로 pid정보와 depth정보를 기록한다.
if (ptr == 0)
{
return;
}
workspace.pId[ptr->id] = pid;
workspace.depth[ptr->id] = depth;
if (ptr->childs)
{
dfs(ptr->id, ptr->childs, depth + 1);
}
if (ptr->siblings)
{
node* siblings = ptr->siblings;
while (siblings)
{
dfs(pid, siblings, depth);
siblings = siblings->siblings;
}
}
return;
}
int LCA(int a, int b)
{
//swap
if (workspace.depth[a] < workspace.depth[b])
{
int tmp = 0;
tmp = a;
a = b;
b = tmp;
}
//a의 depth가 더 깊다. b와 같아질떄까지 올려준다.
while (workspace.depth[a] != workspace.depth[b])
{
a = workspace.pId[a];
}
//깊이가 같아졌으면 공통 조상이 나올때까지 반복한다.
while (a != b)
{
a = workspace.pId[a];
b = workspace.pId[b];
}
return a;
}
int main()
{
int N = 0;
std::cin >> N;
int a, b;
int tmp;
node* a_ptr;
node* b_ptr;
for (int i = 1; i < N; i++)
{
std::cin >> a;
std::cin >> b;
//swap
if (a > b)
{
tmp = b;
b = a;
a = tmp;
}
//build tree here!
if (workspace.idToptr[a] == 0)
{
a_ptr = workspace.idToptr[a] = getNewNode();
a_ptr->id = a;
}
else
{
a_ptr = workspace.idToptr[a];
}
if (workspace.idToptr[b] == 0)
{
b_ptr = workspace.idToptr[b] = getNewNode();
b_ptr->id = b;
}
else
{
b_ptr = workspace.idToptr[b];
}
b_ptr->siblings = a_ptr->childs;
a_ptr->childs = b_ptr;
}
//dfs(int pid, node * ptr, int depth)
dfs(-1, workspace.idToptr[1], 1);
int M = 0;
std::cin >> M;
for (int i = 0; i < M; i++)
{
std::cin >> a;
std::cin >> b;
printf("%d\n", LCA(a, b));
}
return 0;
}