728x90
코딩테스트 연습 - 전력망을 둘로 나누기
9 [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] 3 7 [[1,2],[2,7],[3,7],[3,4],[4,5],[6,7]] 1
programmers.co.kr
📝 문제 설명
n개의 송전탑이 전선을 통해 하나의 트리 형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.
송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절대값)를 return 하도록 solution 함수를 완성해주세요.
⚠️ 제한사항
- n은 2 이상 100 이하인 자연수입니다.
- wires는 길이가
n-1
인 정수형 2차원 배열입니다.- wires의 각 원소는 [v1, v2] 2개의 자연수로 이루어져 있으며, 이는 전력망의 v1번 송전탑과 v2번 송전탑이 전선으로 연결되어 있다는 것을 의미합니다.
- 1 ≤ v1 < v2 ≤ n 입니다.
- 전력망 네트워크가 하나의 트리 형태가 아닌 경우는 입력으로 주어지지 않습니다.
🖨 입출력 예
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 |
📂 분류
그래프 탐색
, 완전탐색
💡 풀이
wires
를 인접 리스트로 만든 후 노드 하나씩 간선을 끊어 각 트리의 노드 개수는 BFS 이용해서 구하는 방식으로 해결했다.
처음 문제를 제출했을 때 오답이 나왔었는데, List<Integer>[] copy = adj
와 같이 참조 값을 복사하는 것이 오답의 원인이었다.
직접 간선을 끊지 않고 BFS를 할 때 해당 노드를 제외해 개수를 구하는 방식도 있었다.
💻 코드
import java.util.*;
class Solution {
List<Integer>[] adj;
boolean[][] checked;
public int solution(int n, int[][] wires) {
int answer = Integer.MAX_VALUE;
checked = new boolean[n][n];
makeGraph(n, wires);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (checked[i][j]) {
continue;
}
List<Integer>[] copyList = copyAList(n);
if (i != j && copyList[j].contains(i)) {
int iToJ = copyList[i].indexOf(j);
int jToI = copyList[j].indexOf(i);
// 간선 끊기
copyList[i].remove(iToJ);
copyList[j].remove(jToI);
int numberOfNodesI = getNumberOfNodes(copyList, i, n);
int numberOfNodesJ = getNumberOfNodes(copyList, j, n);
checked[i][j] = true;
checked[j][i] = true;
answer = Math.min(answer, Math.abs(numberOfNodesI - numberOfNodesJ));
}
}
}
return answer;
}
private List<Integer>[] copyAList(int n) {
List<Integer>[] ret;
ret = new List[n];
for (int i = 0; i < n; i++) {
ret[i] = new ArrayList<>(adj[i]);
}
return ret;
}
private int getNumberOfNodes(List<Integer>[] map, int start, int n) {
Queue<Integer> queue = new LinkedList<>();
boolean[] visited = new boolean[n];
int count = 0;
queue.add(start);
visited[start] = true;
while (!queue.isEmpty()) {
count += 1;
int cur = queue.poll();
for (Integer next : map[cur]) {
if (!visited[next]) {
queue.add(next);
visited[next] = true;
}
}
}
return count;
}
private void makeGraph(int n, int[][] wires) {
adj = new List[n];
for (int i = 0; i < n; i++) {
adj[i] = new ArrayList<>();
}
for (int[] wire : wires) {
int u = wire[0] - 1;
int v = wire[1] - 1;
adj[u].add(v);
adj[v].add(u);
}
}
}
728x90
'Algorithm > 프로그래머스' 카테고리의 다른 글
[JAVA 풀이] 프로그래머스 - 캐시 (2018 KAKAO BLIND RECRUITMENT) (0) | 2022.04.07 |
---|---|
[JAVA 풀이] 프로그래머스 - 모음사전 (Level 2) (0) | 2022.04.06 |
[JAVA 풀이] 프로그래머스 - 교점에 별 만들기 (Level2) (0) | 2022.03.31 |
[JAVA 풀이] 프로그래머스 - 구명보트 (Level2) (0) | 2022.03.23 |
[JAVA 풀이] 프로그래머스 - 주식 가격 (Level 2) (0) | 2022.03.22 |