https://school.programmers.co.kr/learn/courses/30/lessons/86971#
n개의 송전탑이 전선을 통해 하나의 트리
형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.
송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절대값)를 return 하도록 solution 함수를 완성해주세요.
n | wires | result |
---|---|---|
9 | [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] | 3 |
4 | [[1,2],[2,3],[3,4]] | 0 |
7 | [[1,2],[2,7],[3,7],[3,4],[4,5],[6,7]] | 1 |
입출력 예 #1
입출력 예 #2
다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
function solution(n, wires) {
// 최소 절대값 변수
let min = 100;
for (let i = 0; i < wires.length; i++) {
// 잘린 두 그룹을 순히하기 위한 노드
const [firstNode, secondNode] = wires[i];
// 트리 복사
let copy = [...wires];
// 차례대로 잘라보기
copy.splice(i, 1);
// 그래프 만들기
const graph = graphGenerator(copy);
// 두그룹 연결된 송전탑 수 구하기
const firstCnt = dfs(graph, firstNode.toString());
const secondCnt = dfs(graph, secondNode.toString());
// 절대값을 구하고 절대값이 min값보다 작다면 min값을 업데이트
const result = Math.abs(firstCnt - secondCnt);
if (min > result) min = result;
}
return min;
}
const graphGenerator = (arr) => {
let graph = {};
arr.forEach(([v1, v2]) => {
if (graph[v1]) {
graph[v1].push(`${v2}`);
}
if (graph[v2]) {
graph[v2].push(`${v1}`);
}
if (!graph[v1]) {
graph[v1] = [`${v2}`];
}
if (!graph[v2]) {
graph[v2] = [`${v1}`];
}
});
return graph;
};
const dfs = (graph, startNode) => {
// 해당 노드에 연결된 노드가 없다면 자신 하나 뿐
if (!graph[startNode]) return 1;
let needVisitStack = []; // 탐색을 해야 할 노드들
let visitedQueue = []; // 탐색을 마친 노드들
needVisitStack.push(startNode);
// 탐색을 해야 할 노드가 남아 있다면
while (needVisitStack.length !== 0) {
const node = needVisitStack.pop();
if (!visitedQueue.includes(node)) {
visitedQueue.push(node);
needVisitStack = [...needVisitStack, ...graph[node]];
}
}
return visitedQueue.length;
};