728x90
https://programmers.co.kr/learn/courses/30/lessons/86971
문제의 입력은 무조건 트리 형태로 주어집니다.
= 순환 사이클이 없다 = 무조건 루트가 1인 트리 형태로 재배열할 수 있다.
주어진 예제의 경우 다음과 같다.
이렇게 트리 형태로 만들었을 때, 어떻게 가장 차이가 적게 나눌 수 있는가?
자신을 포함한 서브트리의 크기를 계산해서 비교해주면 됩니다.
서브트리의 크기는 dfs로 구할 수 있습니다.
일단 노드가 n개 주어지기 때문에 최대 크기는 n일 것입니다.
그리고 dfs를 진행하는데,
맨 왼쪽의 예제의 경우 1의 서브트리의 크기 = 1+3서브트리 크기
3서브트리 크기=1+2서브트리+4서브트리
4서브트리=1+5서브트리+7서브트리+6서브트리
이런식으로 자식 노드들을 재귀로 탐색해가면서 더해주면 현재 서브트리의 크기를 구할 수 있다.
차이가 가장 적게 하는 전선을 하나 끊어야하는데 그 전선이 뭔지는 알 필요 없고 사이즈의 차이만 비교하면 되기 때문에 섭트리를 진행할때마다 전체 크기와 서브트리의 크기를 비교해주면서 답을 찾으면 됨
import java.util.*;
class Solution {
private static boolean[] visit;
private static List<Integer>[] adj;
private static int min;
public int solution(int n, int[][] wires) {
visit = new boolean[n + 1];
adj = new ArrayList[n + 1];
for (int i = 1; i <= n; i++) {
adj[i] = new ArrayList<>();
}
for (int i = 0; i < n - 1; i++) {
adj[wires[i][0]].add(wires[i][1]);
adj[wires[i][1]].add(wires[i][0]);
}
min = n;
dfs(1, n);
return min;
}
private static int dfs(int node, int n) {
visit[node] = true;
int size = 1;
for (int next : adj[node]) {
if (visit[next])
continue;
size += dfs(next, n);
}
min = Math.min(min, Math.abs(n - 2 * size));
return size;
}
}
'플밍 > 문제풀이' 카테고리의 다른 글
백준17106 : 빙고 (0) | 2023.06.20 |
---|---|
[Java] BOJ1256, 백준 - 사전 (0) | 2022.04.11 |
[Java] BOJ20364, 백준 - 부동산 다툼 (0) | 2022.03.09 |
[Java] BOJ16562, 백준 - 친구비 (0) | 2022.02.25 |
[Java] BOJ1043, 백준 - 거짓말 (0) | 2022.02.25 |