티스토리 뷰
문제
방향그래프가 주어지면 주어진 시작점에서 다른 모든 정점으로의 최단 경로를 구하는 프로그램을 작성하시오. 단, 모든 간선의 가중치는 10 이하의 자연수이다.
입력
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가 주어진다. 셋째 줄부터 E개의 줄에 걸쳐 각 간선을 나타내는 세 개의 정수 (u, v, w)가 순서대로 주어진다. 이는 u에서 v로 가는 가중치 w인 간선이 존재한다는 뜻이다. u와 v는 서로 다르며 w는 10 이하의 자연수이다. 서로 다른 두 정점 사이에 여러 개의 간선이 존재할 수도 있음에 유의한다.
출력
첫째 줄부터 V개의 줄에 걸쳐, i번째 줄에 i번 정점으로의 최단 경로의 경로값을 출력한다. 시작점 자신은 0으로 출력하고, 경로가 존재하지 않는 경우에는 INF를 출력하면 된다.
import java.util.*;
import java.io.*;
public class Main {
static int N;
static List<Edge> map[];
static int[] distances; // 최단거리
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.valueOf(st.nextToken()); // 도시의 개수
int roadCount = Integer.valueOf(st.nextToken());
int startNode = Integer.valueOf(br.readLine());
map = new ArrayList[N + 1];
// 초기 거리는 무한대(INF)로 지정
distances = new int[N + 1];
Arrays.fill(distances, Integer.MAX_VALUE);
for (int i = 1; i <= N; i++) {
map[i] = new ArrayList<>();
}
for (int i = 0; i < roadCount; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.valueOf(st.nextToken());
int to = Integer.valueOf(st.nextToken());
int time = Integer.valueOf(st.nextToken());
map[from].add(new Edge(to, time));
}
// 다익스트라 시작
dijkstra(startNode);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= N; i++) {
if (distances[i] != Integer.MAX_VALUE) {
sb.append(distances[i]+"\\n");
} else {
sb.append("INF\\n");
}
}
System.out.println(sb.toString().trim());
}
private static class Edge implements Comparable<Edge> {
private int from;
private int time;
Edge(int from, int time) {
this.from = from;
this.time = time;
}
// 최단 경로를 위해 compareTo를 오버라이드해준다.
@Override
public int compareTo(Edge o) {
return this.time - o.time;
}
}
private static void dijkstra(int infectiousComputer) {
PriorityQueue<Edge> queue = new PriorityQueue<>();
// 첫 정점의 거리는 0으로 설정
distances[infectiousComputer] = 0;
// 첫 정점과 0을 우선순위 큐에 넣어준다.
queue.add(new Edge(infectiousComputer, 0));
while (!queue.isEmpty()) {
Edge Edge = queue.poll();
int standardNode = Edge.from; // 기준 노드
int time = Edge.time; // 첫 정점에서 기준 노드와의 거리
if (distances[standardNode] < time) {
continue;
}
List<Edge> anotherEdges = map[standardNode]; // 기준 노드에 연결된 노드들의 리스트
for (Edge anotherEdge : anotherEdges) {
int nextFrom = anotherEdge.from; // 해당 노드
/**
* anotherEdge.time - 기준 노드 ~ 해당 노드 거리
* time : 첫 정점 노드 ~ 기준 노드
* 따라서, nextTime은 첫 정점 노드 ~ 기준 노드 ~ 해당 노드 거리
*/
int nextTime = anotherEdge.time + time;
// 첫 정점에서 해당 노드와의 거리(distances[nextFrom]과 nextTime을 비교 후 업데이트
if (distances[nextFrom] > nextTime) {
distances[nextFrom] = nextTime;
// 우선순위 큐에 넣어준다.
queue.add(new Edge(nextFrom, nextTime));
}
}
}
}
}
'알고리즘' 카테고리의 다른 글
BOJ5719 거의 최단 경로 java (0) | 2022.01.31 |
---|---|
BOJ1439 뒤집기 java (0) | 2022.01.30 |
BOJ18352 특정 거리의 도시 찾기 java - 다익스트라 (0) | 2022.01.29 |
최단 경로 문제 (다익스트라) (0) | 2022.01.29 |
BOJ10282 해킹 java (0) | 2022.01.28 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- MSA
- 백준
- 클린 아키텍처
- programmers
- Kotlin
- AWS
- 이팩티브 자바
- Effective Java
- Spring
- 객체지향
- Java
- Spring Boot
- kotest
- BOJ
- 디자인 패턴
- 디자인패턴
- 알고리즘
- 정규표현식
- 클린 코드
- 프로그래머스
- JPA
- 코테
- C++
- kkoon9
- 테라폼
- 이펙티브 자바
- BAEKJOON
- Algorithm
- Olympiad
- node.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함