ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스/JAVA] 전력망을 둘로 나누기
    Algorithm 2024. 9. 18. 11:12

    https://school.programmers.co.kr/learn/courses/30/lessons/86971

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr


    - 문제 풀이

    1. 그래프 초기화

    import java.util.*;
    
    class Solution {
        static ArrayList<Integer>[] graph;
        static int min;
        
        // ... 생략
        graph = new ArrayList[n+1];
            min = Integer.MAX_VALUE; // 자바에서 표현할 수 있는 가장 큰 정수 값
    
            for (int i = 1; i <= n; i++) {
                graph[i] = new ArrayList<>();
                // graph[1] = []
                // graph[2] = []
                // graph[3] = []
                // graph[4] = []
            }

     

     

     + 만약 ArrayList<Integer> graph = new ArrayList<>(); 형태로 작성하면,

    이는 단일 ArrayList로 하나의 정점에만 연결된 값들을 저장하는 구조이다.

    이 경우 전체 그래프를 표현하기보다는 하나의 정점과 그 정점에 연결된 인접 정점만 관리하는 용도로 사용됩니다.

     // 단일 정점에 연결된 인접 정점을 저장하는 리스트
            ArrayList<Integer> graph = new ArrayList<>();
    
            // 인접 정점 추가 (1번 정점에서 연결된 정점들)
            graph.add(2);
            graph.add(3);
            graph.add(5);
    
            // 결과 출력
            System.out.println(graph);
            
            // 결과
            // [2, 3, 5]

     

     

    결과적으로 이 구조는 하나의 정점에 대한 정보만 포함하고 있어,

    여러 정점을 관리하려면 ArrayList[] 배열이나 List<List<Integer>>와 같은 구조가 필요합니다.

     

     

     

    2. 그래프에 연결 정보 추가

    for (int i = 0; i < wires.length; i++) {
                int v1 = wires[i][0];
                int v2 = wires[i][1];
                graph[v1].add(v2);
                graph[v2].add(v1);
                // wires = [[1, 2], [2, 3], [3, 4]] 일때,
                // graph[1] = [2]
                // graph[2] = [1, 3]
                // graph[3] = [2, 4]
                // graph[4] = [3]
            }

     

     

     

     

    3. 연결 정보를 하나씩 끊어서

     for (int i = 0; i < wires.length; i++) {
                int v1 = wires[i][0];
                int v2 = wires[i][1];
    
    
                // 전선을 끊음
                graph[v1].remove(Integer.valueOf(v2));
                graph[v2].remove(Integer.valueOf(v1));

     

    문자열 -> 정수로 변환하려면,

    (Integer.valueOf(), Integer.parseInt() 사용)

     

     

    4. 끊어진 두 전력망 중 하나의 송전탑 개수들 세기

     // DFS로 한 전력망의 송전탑 개수 세기
    		    boolean[] visited = new boolean[n+1];
                int cnt = dfs(1, visited);

     

     // 연결된 송전탑의 개수를 세는 함수
        static int dfs(int v, boolean[] visited) {
            // v: 현재 방문 중인 송전탑 번호
            visited[v] = true;
            int cnt = 1;
    
            for(int next : graph[v]) {
                if (!visited[next]) {
                    cnt += dfs(next, visited);
                }
            }
            return cnt;
        }

     

     

     

    5.  끊어진 두 전력망의 차이 구하기

      // 다른 전력망의 송전탑 개수는 n - cnt
                // Math.abs : 절댓값 구함
                int diff = Math.abs(cnt - (n - cnt));
                min = Math.min(min, diff);
    
                // 전선 복구
                graph[v1].add(v2);
                graph[v2].add(v1);
            }
            return min;

     


     

     

    - 정답 코드

    import java.util.*;
    
    class Solution {
        static ArrayList<Integer>[] graph;
        static int min;
    
        // 연결된 송전탑의 개수를 세는 함수
        static int dfs(int v, boolean[] visited) {
            // v: 현재 방문 중인 송전탑 번호
            visited[v] = true;
            int cnt = 1;
    
            for(int next : graph[v]) {
                if (!visited[next]) {
                    cnt += dfs(next, visited);
                }
            }
            return cnt;
        }
    
        public int solution(int n, int[][] wires) {
            // 1. 그래프 초기화
            graph = new ArrayList[n+1];
            min = Integer.MAX_VALUE; // 자바에서 표현할 수 있는 가장 큰 정수 값
    
            for (int i = 1; i <= n; i++) {
                graph[i] = new ArrayList<>();
                // graph[1] = []
                // graph[2] = []
                // graph[3] = []
                // graph[4] = []
            }
    
            // 2. 그래프에 전선 정보 추가(양방향)
            for (int i = 0; i < wires.length; i++) {
                int v1 = wires[i][0];
                int v2 = wires[i][1];
                graph[v1].add(v2);
                graph[v2].add(v1);
                // wires = [[1, 2], [2, 3], [3, 4]] 일때,
                // graph[1] = [2]
                // graph[2] = [1, 3]
                // graph[3] = [2, 4]
                // graph[4] = [3]
            }
    
            // 3. 전선을 하나씩 끊어서 두 전력망의 송전탑 개수 차이 계산
            for (int i = 0; i < wires.length; i++) {
                int v1 = wires[i][0];
                int v2 = wires[i][1];
    
                boolean[] visited = new boolean[n+1];
    
                // 전선을 끊음
                graph[v1].remove(Integer.valueOf(v2));
                graph[v2].remove(Integer.valueOf(v1));
    
                // DFS로 한 전력망의 송전탑 개수 세기
                int cnt = dfs(1, visited);
    
                // 다른 전력망의 송전탑 개수는 n - cnt
                // Math.abs : 절댓값 구함
                int diff = Math.abs(cnt - (n - cnt));
                min = Math.min(min, diff);
    
                // 전선 복구
                graph[v1].add(v2);
                graph[v2].add(v1);
            }
            return min;
        }
    }

    'Algorithm' 카테고리의 다른 글

    [프로그래머스/JAVA] 카펫  (0) 2024.09.18
    [프로그래머스/JAVA] 소수찾기  (0) 2024.09.18
    [백준/JAVA] 2606번: 바이러스  (0) 2024.07.19
    [백준/JAVA] 21314번: 민겸 수  (0) 2024.07.19
    [백준/JAVA] 1931번: 회의실 배정  (0) 2024.07.18
Designed by Tistory.