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

MINSANG YU·2022년 10월 12일
0

프로그래머스

목록 보기
13/15
post-thumbnail

문제 링크

문제

n개의 송전탑이 전선을 통해 하나의 트리 형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.

송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절대값)를 return 하도록 solution 함수를 완성해주세요.

핵심

인접행렬 또는 인접리스트를 만든 뒤, wires의 길이만큼 반복문을 돌고 wires[i]번째를 제거한 모든 경우의 수를 탐색하는 문제였다.

코드

import java.util.*;

class Solution {
    
    static ArrayList<Integer>[] list;
    static int min;
    static boolean[] visited;
    
    static void dfs(int n, int v1, int v2) {
        for(int num : list[n]) {
            if((n==v1 && num==v2) || (n==v2 && num==v1)) continue; // 3
            if(!visited[num]) { // 4
                visited[num] = true;
                dfs(num,v1,v2);
            }
        }
    }
    
    public int solution(int n, int[][] wires) {
        int answer = -1;
        
        list = new ArrayList[n+1];
        min = Integer.MAX_VALUE/2;
        // 1
        for(int i=1; i<=n; i++) {
            list[i] = new ArrayList<>();
        }
        
        for(int i=0; i<wires.length; i++) {
            int v1 = wires[i][0];
            int v2 = wires[i][1];
            list[v1].add(v2);
            list[v2].add(v1);
        }
        
        for(int i=0; i<wires.length; i++) {
            int v1 = wires[i][0];
            int v2 = wires[i][1];
            visited = new boolean[n+1];
            visited[1] = true;
            // 2
            dfs(1,v1,v2);
            // 5
            int cnt = 0;
            for(int j=1; j<visited.length; j++) {
                if(visited[j]) cnt++;
            }
            min = Math.min(min, Math.abs(n-(2*cnt)));
        }
        
       answer = min;
                           
        return answer;
    }
}
  1. 먼저 문제에서 주어진 n과 wires를 활용해 인접리스트를 만들어줬다.
  2. 인접리스트를 만든 뒤 wires의 크기만큼 반복문을 돌아주고, 각 반복마다 해당되는 v1과 v2를 dfs에 파라미터로 넘겨줬다.
  3. dfs에서 현재 송전탑과 인접리스트에 있는 송전탑이 v1,v2인 경우는 건너뛰고
  4. 인접리스트에 있는 송전탑이 아직 방문하지 않은(연결되지 않은) 송전탑이라면 dfs를 계속 실행시킨다.
  5. dfs가 끝나면 visited 배열에 true라고 저장된 송전탑(cnt개)끼리 연결되어있고, false로 저장된 송전탑 끼리 연결되어 있기 때문에 두 그룹의 차이는 |cnt-(n-cnt)|가 된다.

이후 반복마다 최솟값을 갱신해주면 답을 구할 수 있었다.

profile
쉿! 공부중

0개의 댓글