[프로그래머스] 전력망을 둘로 나누기 (DFS)

2025. 6. 3. 12:53·Algorithm/Coding Test Records

문제 소개

이전 풀었던 전력망을 둘로 나누기 - 프로그래머스 문제 다른 방법으로 정리합니다.
이 문제는 트리 구조에서 간선을 하나 끊어 두 개의 전력망으로 나눌 때, 송전탑 개수 차이를 최소화하는 문제입니다.
유니온 파인드나 DFS 여러 번을 돌릴 수도 있지만, 한 번의 DFS로 서브트리 크기를 이용해 모든 절단 지점을 고려하는 방식이 있어, 참고하여 추가로 정리합니다.

문제 링크: 전력망을 둘로 나누기 - 프로그래머스


문제 접근 방식

이 문제는 다음과 같은 방식으로 접근했습니다:

  1. 트리는 사이클이 없는 무방향 그래프라는 점을 활용
  2. DFS 한 번으로 모든 노드의 서브트리 크기를 계산
  3. 각 노드 기준으로 "이 지점을 절단한다고 가정했을 때" 두 전력망의 송전탑 개수 차이를 계산
  4. 최소 차이값을 갱신하며 답 도출

해결 과정 및 코드

핵심 아이디어

  1. 간선을 실제로 끊지 않고, DFS를 통해 각 노드가 루트인 서브트리의 크기를 계산
  2. 이 서브트리 크기를 기준으로 전체에서 나머지 트리의 크기를 유추
  3. 두 크기 차이를 구해 최소값을 유지

코드

시간 복잡도 : O(N)

import java.util.*;

class Solution {
    int N, min;                     // 전체 송전탑 수와 최소 차이값
    List<Integer>[] graph;         // 인접 리스트로 구성된 트리
    boolean[] visited;             // 방문 여부 체크 (역방향 방지)

    public int solution(int n, int[][] wires) {
        this.N = n;
        this.min = n;

        // 그래프 초기화
        graph = new ArrayList[n + 1];
        for (int i = 1; i <= n; i++) {
            graph[i] = new ArrayList<>();
        }

        // 양방향 간선 정보 등록
        for (int[] wire : wires) {
            int a = wire[0], b = wire[1];
            graph[a].add(b); graph[b].add(a);
        }

        visited = new boolean[n + 1];
        dfs(1); // 루트 노드에서 DFS 시작

        return min;
    }

    // DFS: 서브트리 크기를 반환하면서 두 트리로 나눈 경우 차이 갱신
    private int dfs(int node) {
        visited[node] = true;
        int subtreeSize = 1; // 자기 자신 포함

        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                subtreeSize += dfs(neighbor); // 자식 서브트리 크기 누적
            }
        }

        // 현재 노드에서 절단한다고 가정했을 때 두 트리 차이 계산
        int diff = Math.abs(N - 2 * subtreeSize);
        min = Math.min(min, diff);

        return subtreeSize; // 현재 노드를 루트로 한 서브트리 크기 반환
    }
}

'Algorithm > Coding Test Records' 카테고리의 다른 글

[프로그래머스] 모음사전 (수학)  (0) 2025.06.05
[프로그래머스] 모음사전 (DFS)  (0) 2025.06.04
[프로그래머스] 전력망을 둘로 나누기 (유니온 파인드 Disjoint Set)  (0) 2025.06.02
[프로그래머스] 피로도 (DFS)  (1) 2025.06.01
DFS에서 값을 반환하는 3가지 패턴: 누적, 비교, 조건 반환  (0) 2025.06.01
'Algorithm/Coding Test Records' 카테고리의 다른 글
  • [프로그래머스] 모음사전 (수학)
  • [프로그래머스] 모음사전 (DFS)
  • [프로그래머스] 전력망을 둘로 나누기 (유니온 파인드 Disjoint Set)
  • [프로그래머스] 피로도 (DFS)
Celion
Celion
오늘도 평소처럼 화이팅!
  • Celion
    Orion Log
    Celion
  • 전체
    오늘
    어제
    • 전체 글 (144)
      • Uncompiled Thoughts (8)
        • 네이버 부스트캠프 10기 (5)
      • CS 기초부터 한 걸음씩 (34)
      • Code Odyssey (22)
      • Algorithm (77)
        • Coding Test Records (63)
      • Git (3)
      • reference (0)
  • 블로그 메뉴

    • 태그
    • 방명록
  • 태그

    Kotlin
    java
    알고리즘고득점kit
    프로그래머스
    Level3
    boostcamp
    greedy
    문법정리
    백준
    시뮬레이션
    Level2
    코테
  • 최근 글

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.4
Celion
[프로그래머스] 전력망을 둘로 나누기 (DFS)
상단으로

티스토리툴바