문제 설명
가중치 방향 그래프에서 1번 정점에서 출발하여 각 정점까지의 최소 거리 비용을 구하는 문제입니다.
경로가 존재하지 않는 정점은 "impossible"로 출력합니다.
입력 & 출력
- 입력
- 첫 줄: 정점의 수 N (1 ≤ N ≤ 20), 간선의 수 M
- 다음 M줄: a b c → a번 정점에서 b번 정점으로 가는 간선의 비용은 c
- 출력
- 1번 정점에서 출발해 각 정점까지 가는 최소 거리 출력
- 경로가 없으면 "impossible" 출력

입력 예시
6 9
1 2 12
1 3 4
2 1 2
2 3 5
2 5 5
3 4 5
4 2 2
4 5 5
6 4 5
출력 예시
2 : 11
3 : 4
4 : 9
5 : 14
6 : impossible
해결 방법
- 다익스트라 알고리즘은 가중치가 양수인 그래프에서 최단 경로를 구할 때 사용하는 대표적인 알고리즘입니다.
- PriorityQueue(최소 힙)를 활용해 가장 비용이 적은 정점부터 탐색합니다.
- 방문한 노드보다 더 작은 비용으로 도달 가능한 경우에만 갱신합니다.
코드 구현
class Edge implements Comparable<Edge> {
public int vex, cost;
Edge(int vex, int cost) {
this.vex = vex;
this.cost = cost;
}
public int compareTo(Edge o) {
return this.cost - o.cost;
}
}
public class Problem5 {
static int n, m;
static ArrayList<ArrayList<Edge>> graph;
static int[] dis;
public void solution(int v) {
PriorityQueue<Edge> pQ = new PriorityQueue<>();
pQ.offer(new Edge(v, 0));
dis[v] = 0;
while (!pQ.isEmpty()) {
Edge tmp = pQ.poll();
int now = tmp.vex;
int nowCost = tmp.cost;
if (nowCost > dis[now]) continue;
for (Edge ob : graph.get(now)) {
if (dis[ob.vex] > nowCost + ob.cost) {
dis[ob.vex] = nowCost + ob.cost;
pQ.offer(new Edge(ob.vex, nowCost + ob.cost));
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
graph = new ArrayList<>();
for (int i = 0; i <= n; i++) graph.add(new ArrayList<>());
dis = new int[n + 1];
Arrays.fill(dis, Integer.MAX_VALUE);
for (int i = 0; i < m; i++) {
int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
graph.get(a).add(new Edge(b, c));
}
new Problem5().solution(1);
for (int i = 2; i <= n; i++) {
System.out.println(i + " : " + (dis[i] == Integer.MAX_VALUE ? "impossible" : dis[i]));
}
sc.close();
}
}
주요 코드 설명
- Edge 클래스
- 그래프의 간선을 표현 (도착 정점 vex, 비용 cost)
- Comparable을 구현하여 PriorityQueue에서 비용이 작은 순으로 꺼낼 수 있도록 정렬
- graph
- 인접 리스트 형태의 그래프 구조 (ArrayList<ArrayList<Edge>>)
- graph.get(a)는 a번 정점에서 출발하는 모든 간선 리스트를 가짐
- dis 배열
- dis[i]: 1번 정점에서 i번 정점까지의 최소 거리를 저장
- 처음에는 모두 Integer.MAX_VALUE로 초기화 → 아직 방문하지 않음
- solution(int v)
- 다익스트라 알고리즘 실행 함수
- 시작점 v(1번 정점)에서 우선순위 큐에 (정점, 0) 넣고 시작
- 우선순위 큐에서 가장 비용이 적은 정점을 꺼내며 인접 정점을 탐색
- nowCost > dis[now]이면 이미 더 짧은 경로로 방문했으므로 스킵
- 더 짧은 거리로 갈 수 있으면 dis 갱신하고 큐에 넣음
- main() 함수
- 정점 수 n, 간선 수 m 입력
- 그래프 초기화 및 간선 정보 입력
- 1번 정점에서 다익스트라 실행
- 2번부터 n번 정점까지의 최단 거리 출력
- dis[i] == Integer.MAX_VALUE면 도달할 수 없으므로 "impossible" 출력
시간 복잡도
- 정점 수 N, 간선 수 M일 때
- 우선순위 큐 연산 (삽입/삭제): O(log N)
- 모든 정점 처리: 최대 N번 → O(N log N)
- 모든 간선 확인: 각 간선마다 큐 삽입 가능 → O(M log N)
- 총 시간 복잡도: O((N + M) log N)
- 이 문제는 N ≤ 20, M ≤ 100 이므로 충분히 빠르게 처리 가능
출처: 인프런 자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
https://www.inflearn.com/course/자바-알고리즘-문제풀이-코테대비/dashboard
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비 강의 | 김태원 - 인프런
김태원 | , 자바(Java) 알고리즘 문제풀이 채점사이트를 통해 기초부터 준비해보세요! 💪 [사진] 이 강의는 [사진] 자바(Java)로 코딩테스트 준비를 하고 계신 분께 추천드려요! 문제는 기초~ 중급
www.inflearn.com
'코딩테스트 > 자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비' 카테고리의 다른 글
| 섹션 9 Greedy - 7. 원더랜드(최소스패닝트리 - 크루스칼 : Union&Find 이용) (0) | 2025.06.12 |
|---|---|
| 섹션 9 Greedy - 6. 친구인가?(Disjoint-Set : Union&Find) (0) | 2025.06.12 |
| 섹션 9 Greedy - 4. 최대 수입 스케쥴(PriorityQueue 응용문제) (0) | 2025.06.11 |
| 섹션 9 Greedy - 3. 결혼식 (1) | 2025.06.10 |
| 섹션 9 Greedy - 2. 회의실 배정 (0) | 2025.06.10 |