[백준] 1916 : 최소비용 구하기 (JAVA)

2024. 11. 13. 12:00·Algorithm

https://www.acmicpc.net/problem/1916

 

🚩다익스트라 (Dijkstra)

 

1916번 문제를 보자마자 기본적인 다익스트라 알고리즘으로 해결할 수 있겠다고 생각을 했습니다. 평소에 알고 있던 다익스트라 방식으로 구현을 진행했고, 예제 출력도 정상적으로 나왔기 때문에 정답 제출을 했는데요..

 

 

결과는 시간 초과입니다🥲

15% 지점에서 계속 시간 초과가 발생했고, 문제를 다시 확인해 보니 시간제한이 0.5초 인걸 확인할 수 있었습니다.

 

시간 복잡도를 개선하기 위해 코드 분석을 해봤지만 문제의 원인은 찾지 못했고 검색을 통해 해결책을 찾아보니, queue에서 poll() 연산을 수행할 때 해동 노드의 방문 여부를 확인하는 처리가 필요하다는 것을 알게 되었습니다.

 

'근데.. queue.add를 수행하기 전에 이미 방문 여부를 확인하고, 미방문을 노드만 추가하는데, 왜 poll() 시점에 다시 방문 처리를 해야 하는 걸까?'라는 의문이 들었습니다.

 

 

🤔 2번 방문 확인하는 이유는 뭐지..?

 

코드를 디버깅해본 결과, 아직 미방문 상태인 5번 노드에 대한 요청이 두 번 발생했고, 이로 인해 방문 PriorityQueue을 사용하고 있음에도 불구하고 동일한 노드에 대한 처리가 중복으로 수행되고 있었습니다.

 

이러한 중복 처리를 방지하고 실행 시간을 최적화하기 위해, poll() 연산 이후에 방문 여부를 한 번 더 확인하는 것이 필요했던 것입니다!

 


 

아래는 제출한 코드입니다.

import java.io.*;
import java.util.*;

class Node {
    int end;
    int weight;

    public Node(int end, int weight) {
        this.end = end;
        this.weight = weight;
    }
}

public class Main {

    static ArrayList<Node>[] al;
    static int[] result;
    static boolean[] visited;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());

        al = new ArrayList[N + 1];
        result = new int[N + 1];
        visited = new boolean[N + 1];

        for (int i = 1; i <= N; i++) {
            al[i] = new ArrayList<>();
            result[i] = Integer.MAX_VALUE;
        }

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());

            al[a].add(new Node(b, c));
        }

        st = new StringTokenizer(br.readLine());
        int start = Integer.parseInt(st.nextToken());
        int end = Integer.parseInt(st.nextToken());

        result[start] = 0;
        djk(start);

        bw.write(result[end] + "");
        bw.close();
    }

    public static void djk(int start) {
        PriorityQueue<Node> queue = new PriorityQueue<>((o1, o2) -> o1.weight - o2.weight);
        queue.add(new Node(start, 0));

        while (!queue.isEmpty()) {
            Node now = queue.poll();

            if (visited[now.end]) continue;	// 추가한 코드

            for (Node next : al[now.end]) {
                if (!visited[next.end]) {
                    if (next.weight + result[now.end] < result[next.end]) {
                        result[next.end] = next.weight + result[now.end];
                        queue.add(new Node(next.end, result[next.end]));
                    }
                }
            }
            visited[now.end] = true;
        }
    }
}

'Algorithm' 카테고리의 다른 글

[백준] 16139 : 인간-컴퓨터 상호작용 (JAVA)  (0) 2024.12.02
[백준] 10816 : 숫자 카드 2 (JAVA)  (0) 2024.11.18
[백준] 16953 : A -> B (JAVA)  (1) 2024.11.10
[백준] 11054 : 가장 긴 바이토닉 부분 수열 (JAVA)  (1) 2024.11.08
[백준] 13549 : 숨바꼭질 3 (JAVA)  (0) 2024.11.05
'Algorithm' 카테고리의 다른 글
  • [백준] 16139 : 인간-컴퓨터 상호작용 (JAVA)
  • [백준] 10816 : 숫자 카드 2 (JAVA)
  • [백준] 16953 : A -> B (JAVA)
  • [백준] 11054 : 가장 긴 바이토닉 부분 수열 (JAVA)
chanyoungdev
chanyoungdev
chanyoungdev
  • chanyoungdev
    Young Code
    chanyoungdev
  • 전체
    오늘
    어제
    • 분류 전체보기 (28)
      • Programming (12)
        • Java (0)
        • Spring (10)
        • etc (2)
      • Data Infra (5)
        • Database (1)
        • Redis (2)
        • etc (2)
      • DevOps (4)
        • CI CD (1)
        • Nginx (2)
        • Docker (0)
        • Aws (0)
        • etc (1)
      • Algorithm (6)
      • etc (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • First Tech Blog
    • Github
  • 공지사항

  • 인기 글

  • 태그

    공통 응답
    cache
    Redis
    Mockito
    infra architecture
    nginx
    junit
    Infra
    Spring Batch
    단위 테스트
    캐시
    JWT
    ssl
    Algorithm
    domain
    spring security
    Virtual Thread
    elasticsearch
    lock
    OAuth
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
chanyoungdev
[백준] 1916 : 최소비용 구하기 (JAVA)
상단으로

티스토리툴바