[알고리즘 - 그래프] 다익스트라 - 가장 먼 노드

2023. 3. 30. 12:48·개발 공부/알고리즘

문제

문제 링크

풀이

이 문제는 하나의 노드에서 다른 모든 노드까지의 최소 경로를 구하는 문제로 다익스트라 알고리즘을 이용해 풀이할 수 있다.

다익스트라 알고리즘

다익스트라 알고리즘은 아래와 같은 방식으로 동작한다.

  1. 출발 노드 설정
  2. 최단 거리 테이블 초기화
  3. 방문하지 않은 && 최단 거리가 가장 짧은 노드를 선택
  4. 3에서 선택한 노드를 거쳐 다른 노드로 가는 비용을 계산해 최단 거리 테이블을 갱신
  5. 끝날 때 까지 3, 4번 과정을 반복

문제의 테스트 케이스에 적용

  1. 1번 노드부터 나머지 노드로의 최단 경로를 구하는 문제이므로 출발 노드는 1번으로 설정
  2. 간선에 가중치가 없으므로 출발노드와 이웃하는 노드까지의 거리를 1로 설정

image-20230330123046609

image-20230330123630196

  1. 방문하지 않은 노드 중 최단 경로가 최소인 2(또는 3)번 노드를 선택
  2. 이웃한 노드의 최단 경로를 갱신

image-20230330123719653

  1. 방문하지 않은 노드 중 최단 경로가 최소인 3번 노드를 선택
  2. 이웃한 노드의 최단 경로를 갱신

image-20230330123828505

이 과정을 끝까지 반복하면 아래와 같은 상태가 된다.

image-20230330123818438

따라서 최단 경로가 최대인 노드의 개수는 3개이다.

그리디 알고리즘

다익스트라 알고리즘은 매 단계마다 최초 노드에서 경로가 최단인 노드를 선택하고 선택된 노드의 최단 경로를 그 시점에 확정하기 때문에 매 시점에 가장 최적의 해를 선택한다는 점에서 그리디 알고리즘에 속한다고 할 수 있다.

코드 (설명 포함)

import java.util.*;

class Solution {

    // 우선순위 큐에서 사용하기 위한 Node 클래스
    static class Node implements Comparable<Node>{
        int index; // 현재 노드의 index
        int currentDistance; // 현재 노드의 현재까지의 최단 경로

        Node(int index, int currentDistance) {
            this.index = index;
            this.currentDistance = currentDistance;
        }

        // 우선순위 큐에서 대소 비교를 위해 Comparable 인터페이스를 구현해야 함
        @Override
        public int compareTo(Node other) {
            return this.currentDistance - currentDistance;
        }
    }

    public int solution(int n, int[][] edge) {
        int[] distances = new int[n + 1]; // 매 시점 노드까지의 최단거리를 저장
        Arrays.fill(distances, Integer.MAX_VALUE); // 최초엔 무한(도달 불가)으로 채우기

        List<List<Integer>> graph = new ArrayList<>(); // 각 노드와 이웃한 노드 리스트를 저장

        // graph 초기화
        for (int i = 0 ; i <= n ; i++) {
            graph.add(new ArrayList<>());
        }
        // 이웃 노드 정보 추가 (양방향)
        for (int[] e : edge) {
            graph.get(e[0]).add(e[1]);
            graph.get(e[1]).add(e[0]);
        }

        // 다익스트라 알고리즘 시작

        // 매 step에 가장 최단 경로가 짧은 노드를 선택하기 위해 반복문을 도는 대신 우선순위 큐를 사용
        PriorityQueue<Node> queue = new PriorityQueue<>();
        // 초기 (1번) 노드 설정
        queue.offer(new Node(1, 0)); // Node(index, currentDistance)
        distances[1] = 0;

        while(!queue.isEmpty()) {
            Node currentNode = queue.poll();
            // 이전에 방문한 노드면 제외
            // 우선순위 큐에서 빼온 currentDistance 값이 최단 경로 테이블에 기록된 최소 경로 값보다 크면
            // 이미 방문한 노드이므로 처리할 필요 없음
            if (currentNode.currentDistance > distances[currentNode.index]) {
                continue;
            }

            // 연결된 노드들 갱신
            for (int neighbor : graph.get(currentNode.index)) {
                int newDistance = distances[currentNode.index] + 1;
                // 새로운 경로가 더 짧을 경우에만 최단 경로 테이블 갱신 및 큐에 추가
                if (newDistance < distances[neighbor]) {
                    distances[neighbor] = newDistance;
                    queue.offer(new Node(neighbor, newDistance));
                }
            }       
        }

        // 최대 경로가 몇인지 탐색
        int maxDistance = 0;
        for (int i = 1 ; i <= n ; i++) {
            maxDistance = Math.max(maxDistance, distances[i]);
        }

        // 최대 경로를 갖는 노드가 몇 개인지 탐색
        int count = 0;
        for (int distance : distances) {
            if (distance == maxDistance) {
                count++;
            }
        }
        return count;
    }
}

참고자료

  • https://www.youtube.com/watch?v=acqm9mM1P6o&list=PLRx0vPvlEmdAghTr5mXQxGpHjWqSz0dgC&index=7

'개발 공부 > 알고리즘' 카테고리의 다른 글

[알고리즘 - 완전탐색] 전력망을 둘로 나누기  (0) 2023.04.13
[알고리즘] 전화번호 목록  (0) 2023.04.06
[알고리즘 - graph] 네트워크  (0) 2023.03.23
[알고리즘] graph와 탐색  (0) 2023.03.21
[알고리즘 - DP] 프로그래머스 - 등굣길  (0) 2023.03.16
'개발 공부/알고리즘' 카테고리의 다른 글
  • [알고리즘 - 완전탐색] 전력망을 둘로 나누기
  • [알고리즘] 전화번호 목록
  • [알고리즘 - graph] 네트워크
  • [알고리즘] graph와 탐색
gmelon
gmelon
백엔드 개발을 공부하고 있습니다.
  • gmelon
    gmelon's greenhouse
    gmelon
  • 전체
    오늘
    어제
    • 분류 전체보기 (91)
      • 개발 공부 (28)
        • Java (6)
        • Spring (10)
        • 알고리즘 (11)
        • 기타 (1)
      • 프로젝트 (12)
        • [앱] 플랭고 (4)
        • 졸업 프로젝트 (8)
      • 스터디 (0)
        • 자바 (30)
      • 기록 (15)
        • 후기, 회고 (9)
        • SSAFYcial (5)
        • 이것저것 (1)
      • etc. (6)
        • 모각코 (6)
  • 블로그 메뉴

    • 홈
    • 방명록
    • github
    • 스크랩
  • 인기 글

  • 태그

    2024 회고
    groupingBy()
    졸업프로젝트
    한글프로그래밍언어
    java
    Collector groupingBy()
    자바 Collector
    싸피 회고
    2024 상반기 회고
    AWS 프리티어 종료
    태초마을이야
    Java Collector
    프리티어 종료
    groupingBy mapping
    자바
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
gmelon
[알고리즘 - 그래프] 다익스트라 - 가장 먼 노드
상단으로

티스토리툴바