1. 그래프 만들기
function makeConnection(n, edges) {
const con = Array.from({ length: n }, () => []);
edges.forEach(([node1, node2]) => {
con[node1].push(node2);
con[node2].push(node1);
});
return con;
}
2. 깊이와 조상
function makeDepth(root, con) {
const size = con.length;
const depth = Array(size);
const ancs = Array.from({ length: size }, () => []);
const stack = [];
con[root].forEach((node) => stack.push([node, root]));
depth[root] = 0;
while (stack.length) {
const [cur, parent] = stack.pop();
depth[cur] = depth[parent] + 1;
ancs[cur][0] = parent;
const ancLimit = Math.floor(Math.log2(depth[cur]));
for (let i = 1; i <= ancLimit; i += 1) {
const anc = ancs[cur][i - 1];
ancs[cur][i] = ancs[anc][i - 1];
}
con[cur].forEach((node) => {
if (node !== parent) stack.push([node, cur]);
});
}
return [depth, ancs];
}
3. LCA
function getSameDpethAnc(node, target, ancs, depth) {
let left = 0;
let right = ancs[node].length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const anc = ancs[node][mid];
const comp = depth[anc] - depth[target];
if (comp === 0) return ancs[node][mid];
if (comp > 0) left = mid + 1;
else right = mid - 1;
}
return ancs[node][right];
}
function lca(a, b, ancs, depth) {
let [deep, shallow] = depth[a] < depth[b] ? [b, a] : [a, b];
while (depth[deep] !== depth[shallow]) {
deep = getSameDpethAnc(deep, shallow, ancs, depth);
}
if (deep !== shallow) {
for (let i = ancs[deep].length - 1; i >= 0; i -= 1) {
if (i < ancs[deep].length && this.ancs[deep][i] !== this.ancs[shallow][i]) {
deep = ancs[deep][i];
shallow = ancs[shallow][i];
}
}
deep = ancs[deep][0];
shallow = ancs[shallow][0];
}
return deep;
}