본문 바로가기
알고리즘 문제/백준

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

by 건복치 2021. 3. 16.
반응형

문제

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

 

1916번: 최소비용 구하기

첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)이 주어지고 둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그

www.acmicpc.net

설명

다익스트라 알고리즘을 이용하면 쉽게 풀 수 있는 문제다.

 

📌 다익스트라 알고리즘에 대해 알고 싶다면 아래 포스팅을 확인해주세요.

 

[Java] 다익스트라 (Dijkstra) 최단 경로 알고리즘

전체 코드

* 무한대를 처음엔 Integer.MAX_VALUE로 했는데 오버플로우가 나는지 채점 중 런타임 에러가 났다ㅠㅠ

무한대 값을 Integer.MAX_VALUE-1 로 하면 안남...왜지?

 

* 백준 사이트에서 알아본 결과

INF는 항상 (간선 가중치의 최댓값) * (정점 개수 - 1) 보다 큰 값을 사용해야 합니다. 

거리가 가장 멀어지는 경우를 생각해 보면, 1-2-3-4-5-6-...-V 이렇게 일직선으로 모든 간선이 최대 가중치를 가지고 연결되어 있을 때 

총 V-1개의 간선을 전부 차례대로 지나가야 하기 때문입니다. 

 

따라서 무작정 Integer.MAX_VALUE처럼 제일 큰 값 말고 int INF = 100000 * (N-1); 와 같이 INF를 설정 후 푸는 것이 좋을 것 같다.

 

import java.util.Arrays;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();
		int M = sc.nextInt();

		int[][] arr = new int[N+1][N+1];
		for(int i = 1; i < N+1; i++) {
			Arrays.fill(arr[i], -1); // 가중치 0이 있을수도 있으니 -1로 초기화 
		}

		for(int i = 0; i < M; i++) {
			int a = sc.nextInt();
			int d = sc.nextInt();
			int c = sc.nextInt();

			// 시작 정점과 도착 정점이 같은데 비용이 다른 값이 들어올 수 있기 때문에 예외 처리 
			if(arr[a][d] == -1) 
				arr[a][d] = c;
			else if(arr[a][d] > c) 
				arr[a][d] = c;
		}

		int start = sc.nextInt();
		int end = sc.nextInt();

		boolean[] check = new boolean[N+1]; // 정점이 집합 S에 속하는지 아닌지를 판별할 배열 

		int[] distance = new int[N+1]; // 최단 거리를 담을 배열 
		Arrays.fill(distance, Integer.MAX_VALUE-1); // 무한대로 초기화 

		distance[start] = 0;

		for(int i = 0; i < N-1; i++) { // 시작점을 넣고 시작하기 때문에 N-1만큼만 반복 
			int min = Integer.MAX_VALUE;
			int index = -1;

			// 집합 S에 속하지 않는 가장 최단 거리를 갖는 정점 선택함 
			for(int j = 1; j < N+1; j++) { 
				if(!check[j] && distance[j] < min) {
					min = distance[j]; // 최단 거리 
					index = j; // 최단 거리를 갖는 정점의 index 
				}
			}

			check[index] = true;

			// S에 속하지 않는다면 더 작은 값을 갖는 거리로 distance값 갱신 
			for (int j = 1; j < N+1; j++) { 
				if (!check[j] && arr[index][j] != -1 && distance[index] + arr[index][j] < distance[j]) { // 간선이 연결되지 않은 -1의 경우 역시 제외해야함 
					distance[j] = distance[index] + arr[index][j];
				}
			}
		}

		System.out.println(distance[end]); // 도착점까지의 최단 거리 출력 
	}

}

GITHUB

 

 

KwonMinha/BOJ

Baekjoon Online Judge(Java) 문제풀이. Contribute to KwonMinha/BOJ development by creating an account on GitHub.

github.com

 

반응형

댓글