Lowest Common Ancestor - changicho/algorithm-training GitHub Wiki
์ต์ ๊ณตํต ์กฐ์ (Lowest Common Ancestor)
๊ด๋ จ ๋ฌธ์
๋ฐฑ์ค.1761.์ ์ ๋ค์ ๊ฑฐ๋ฆฌ
ํ์ํ ์๋ฃ๊ตฌ์กฐ
struct Node {
int to, weight;
};
์๋ฆฌ
LCA๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ ํธ๋ฆฌ๋ค์ ์ต์ ๊ณตํต ์กฐ์์ ๊ตฌํ ์ ์๋ค.
๋ ธ๋ A์ B์ ๋์ด๋ฅผ ๋ง์ถฐ์ค ๋ค, ํ๋จ๊ณ์ฉ ์ฌ๋ผ๊ฐ๋ฉฐ ์กฐ์์ ์ฐพ๋ ๋ฐฉ์์ด๋ค.
์ด์ ์ ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํด ๊ฐ ๋ ธ๋๋ค์ ๋ถ๋ชจ๋ฅผ ๊ฐฑ์ ํด์ผ ํ๋๋ฐ, ์ด๋ฅผ ์ํด์ ๋ค์๊ณผ ๊ฐ์ ๋ฐฐ์ด๋ค์ด ํ์ํ๋ค.
// node : ๋
ธ๋์ ์ต๋ ๊ฐ์ (MAX)
// level : log_w(MAX) + 1 (MAX_LEVEL)
bool visited[node]; // ๋
ธ๋ ๋ฐฉ๋ฌธ ์ฌ๋ถ
int parents[node][level]; // ๋ฐฐ์ด(node: ์ ์ ๋ฒํธ level: 2^level๋ฒ์งธ ์กฐ์์ ์๋ฏธ)
int depths[node]; // node์ ๋์ด๊ฐ ๋ช์ธ์ง
int distArray[node]; // ๋ฃจํธ๋ถํฐ ๊ฐ ๋
ธ๋๋ค ๊น์ง์ ๊ฑฐ๋ฆฌ
์ฌ๊ทํจ์์ ๋ฐ๋ณต๋ฌธ์ ์ด์ฉํด ์ด๊ธฐ๊ฐ์ ์ค์ ํ๋ค.
// distance ๋ถ๋ถ์ ์ํฉ์ ๋ฐ๋ผ์ ๊ณ ๋ ค
void recursive(int current, int depth, int distance) {
visited[current] = true;
depths[current] = depth;
distArray[current] = distance;
for (int next : graph[current]) {
if (visited[next]) continue;
parents[next][0] = current;
recursive(next, depth + 1, distance + weights[current]);
}
}
recursive(rootNode, 0); // ๋ฃจํธ๋
ธ๋, 0
for (int level = 1; level <= MAX_LEVEL; level++) {
for (int node = 1; node <= N; node++) {
int parent = parents[node][level - 1];
parents[node][level] = parents[parent][level - 1];
}
}
์ต์ ๊ณตํต ์กฐ์์ ์ฐพ๋ ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
int lowestCommonAncestor(int first, int second) {
// ์ฒซ๋ฒ์งธ๊ฐ ์์ ๋
ธ๋ ๋์ด๋ฅผ ๋ ๋ฎ๋๋ก ์ค์
if (depths[first] > depths[second]) {
swap(first, second);
}
// ๋์ด๋ฅผ ๋ง์ถฐ์ค
for (int level = MAX_LEVEL; level >= 0; level--) {
if (depths[second] - depths[first] >= (1 << level)) {
second = parents[second][level];
}
}
if (first == second) {
return first;
}
for (int level = MAX_LEVEL; level >= 0; level--) {
if (parents[first][level] != parents[second][level]) {
first = parents[first][level];
second = parents[second][level];
}
}
return parents[first][0];
}