최코딩의 개발

[백준 1916번] 최소비용 구하기 본문

코딩테스트/백준

[백준 1916번] 최소비용 구하기

seung_ho_choi.s 2025. 2. 25. 19:18
728x90

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

 

수정 전

package graph;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Map;
import java.util.StringTokenizer;

public class Graph1916 {
    static int end = 0;

    static int N = 0;
    static int answer = 0;

    static int min = Integer.MAX_VALUE;

    static int[][] map;
    static int compare = Integer.MAX_VALUE;

    static boolean[][] visit;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        // 배열 선언 및 -1로 채우기
        map = new int[N + 1][N + 1];
        visit=new boolean[N+1][N+1];
        for (int i = 0; i < N + 1; i++) {
            Arrays.fill(map[i], -1);
        }

        // 도시 이동 별 가중치 입력 받기
        StringTokenizer st;
        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 value = Integer.parseInt(st.nextToken());
            map[a][b] = value;
        }

        // 출발 도시 및 도착 도시 선택 하기
        st = new StringTokenizer(br.readLine());
        start = Integer.parseInt(st.nextToken());
        end = Integer.parseInt(st.nextToken());

        solution(start);
        System.out.println(min);
    }

    static void solution(int start) {
        if (start == end) {
            min = Math.min(min, answer);
            compare = min;
        }

        for (int i = 1; i <= N; i++) {
            if (start != i && map[start][i] != -1 && !visit[start][i]) {
                int value = map[start][i];
                if (compare > answer + value) {
                    answer += value;
                    visit[start][i]=true;
                    solution(i);
                    answer -= value;
                    visit[start][i]=false;
                }
            }
        }
    }
}

 

수정 후

package graph;

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

public class Graph1916 {
    static class Node implements Comparable<Node> {
        int city, cost;
        public Node(int city, int cost) {
            this.city = city;
            this.cost = cost;
        }

        @Override
        public int compareTo(Node o) {
            return Integer.compare(this.cost, o.cost);
        }
    }

    static int N, M;
    static List<List<Node>> graph;
    static int[] dist;
    static final int INF = Integer.MAX_VALUE;

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

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

        // 그래프 초기화
        graph = new ArrayList<>();
        for (int i = 0; i <= N; i++) {
            graph.add(new ArrayList<>());
        }

        // 버스 정보 입력
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
            int cost = Integer.parseInt(st.nextToken());
            graph.get(from).add(new Node(to, cost));
        }

        // 출발지와 도착지 입력
        st = new StringTokenizer(br.readLine());
        int start = Integer.parseInt(st.nextToken());
        int end = Integer.parseInt(st.nextToken());

        // 다익스트라 실행
        int answer = dijkstra(start, end);
        System.out.println(answer);
    }

    static int dijkstra(int start, int end) {
        PriorityQueue<Node> pq = new PriorityQueue<>();
        dist = new int[N + 1];
        Arrays.fill(dist, INF);

        pq.add(new Node(start, 0));
        dist[start] = 0;

        while (!pq.isEmpty()) {
            Node now = pq.poll();
            int curCity = now.city;
            int curCost = now.cost;

            // 현재 노드까지의 비용이 기존보다 크다면 스킵
            if (curCost > dist[curCity]) continue;

            for (Node next : graph.get(curCity)) {
                int nextCity = next.city;
                int nextCost = curCost + next.cost;

                if (nextCost < dist[nextCity]) {
                    dist[nextCity] = nextCost;
                    pq.add(new Node(nextCity, nextCost));
                }
            }
        }

        return dist[end];
    }
}

 

 

일반적인 다익스트라 문제다. 처음에는 백트래킹을 사용해 풀었지만, 시간 초과가 발생했다.
그래서 우선순위 큐를 이용한 다익스트라 알고리즘을 적용했다.
핵심은 한 번에 하나씩 경로를 탐색하는 것이 아니라, BFS 방식으로 동시에 여러 경로를 탐색하는 것이다.

728x90

'코딩테스트 > 백준' 카테고리의 다른 글

[백준 12865번] 평범한 배낭  (1) 2025.02.28
[백준 9251번] LCS  (1) 2025.02.27
[백준 1244번] 스위치 켜고 끄기  (0) 2025.02.10
[백준 2503번] 숫자 야구  (0) 2025.02.09
[백준 1966번] 프린터 큐  (0) 2025.02.08