[프로그래머스] 전력망을 둘로 나누기 (유니온 파인드 Disjoint Set)

2025. 6. 2. 12:23·Algorithm/Coding Test Records

문제 소개

오늘 풀었던 전력망을 둘로 나누기 - 프로그래머스 문제를 정리합니다.
이 문제는 트리 구조에서 간선 하나를 끊어 두 개의 서브트리로 나눌 때, 송전탑 개수 차이를 최소화하는 경우를 찾는 문제입니다.

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


문제 접근 방식

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

  1. 모든 간선에 대해 하나씩 끊어보기
  2. 간선을 끊은 상태에서 유니온 파인드로 두 집합 구성
  3. 각 집합 크기를 계산 후 차이를 기록
  4. 최소 차이를 정답으로 선택

해결 과정 및 코드

핵심 아이디어

  1. 전선 하나를 끊으면 두 개의 트리로 나뉨 → 이 두 트리의 송전탑 개수 차이를 구함
  2. 간선 하나를 제외한 상태에서 유니온 파인드를 통해 서로소 집합 구성
  3. 각 송전탑의 루트를 찾고, 루트 기준으로 카운팅하여 두 트리 크기 비교
  4. 이 작업을 모든 간선에 대해 반복하며 최소 차이값을 업데이트

코드

시간 복잡도 : O(E × N)

import java.util.*;

class Solution {
    static int [] parents;
    public int solution(int n, int[][] wires) {
        int answer = Integer.MAX_VALUE;
        parents = new int[n+1];
        for (int i = 0; i < wires.length; i++) {
            cuttingWires(n, i, wires); // 간선 하나 제거
            answer = Math.min(answer, countDiff(parents)); // 두 트리 차이 계산
        }
        return answer;
    }
    
    // 간선 i번째를 제외하고 나머지로 유니온 파인드 구성
    private void cuttingWires(int n, int cuttingIdx, int[][] wirtes){
        init();
        for (int i = 0; i < wirtes.length; i++) {
            if (i == cuttingIdx) continue;
            union(wirtes[i][0], wirtes[i][1]);
        }
    }
    
    // 두 집합의 크기 차이 계산
    private int countDiff(int[] parents) {
        int n = parents.length - 1;
        int root = find(1), count = 0;
        for (int i = 1; i <= n; i++) {
            if (find(i) == root) count++;
        }
        return Math.abs((n - count) - count);
    }
    
    // 서로소 집합 초기화
    private void init(){
        for (int i = 1; i < parents.length; i++) {
            parents[i] = i;
        }
    }
    
    // 루트 찾기 (경로 압축)
    private int find(int a){
        if (parents[a] == a) return a;
        return parents[a] = find(parents[a]); // 경로 압축
    }
    
    // 집합 합치기
    private void union(int a, int b){
        int rootA = find(a), rootB = find(b);
        parents[rootB] = rootA;
    }
}

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

[프로그래머스] 모음사전 (DFS)  (0) 2025.06.04
[프로그래머스] 전력망을 둘로 나누기 (DFS)  (0) 2025.06.03
[프로그래머스] 피로도 (DFS)  (1) 2025.06.01
DFS에서 값을 반환하는 3가지 패턴: 누적, 비교, 조건 반환  (0) 2025.06.01
[프로그래머스] 카펫 (구현)  (0) 2025.05.31
'Algorithm/Coding Test Records' 카테고리의 다른 글
  • [프로그래머스] 모음사전 (DFS)
  • [프로그래머스] 전력망을 둘로 나누기 (DFS)
  • [프로그래머스] 피로도 (DFS)
  • DFS에서 값을 반환하는 3가지 패턴: 누적, 비교, 조건 반환
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)
  • 블로그 메뉴

    • 태그
    • 방명록
  • 태그

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

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.4
Celion
[프로그래머스] 전력망을 둘로 나누기 (유니온 파인드 Disjoint Set)
상단으로

티스토리툴바