반응형
728x90
반응형
문제
https://www.acmicpc.net/problem/1238
1238번: 파티
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), X가 공백으로 구분되어 입력된다. 두 번째 줄부터 M+1번째 줄까지 i번째 도로의 시작점, 끝점, 그리고 이 도로를 지나는데 필요한 소요시간 Ti가 들어
www.acmicpc.net
다익스트라 알고리즘
https://devfunny.tistory.com/641?category=905091
최단 경로 알고리즘 - 다익스트라 알고리즘 우선순위 큐 사용 버전
들어가기전 기본 다익스트라 알고리즘에 대해 먼저 공부하자. https://devfunny.tistory.com/638 최단 경로 알고리즘 - 다익스트라 알고리즘 기본 버전 최단 경로 알고리즘 (Shortest Path) 가장 짧은 경로를
devfunny.tistory.com
풀이코드
package com.algorithm._00_._Current;
import java.util.*;
import java.util.stream.IntStream;
/**
* @Date 2022/03/15
* @URL https://www.acmicpc.net/problem/1238
*/
public class _1238_파티 {
/* 무한을 의미하는 값으로 10억을 설정 */
public static final int INF = (int) 1e9;
public static int n; // 노드의 개수(N)
public static int m; // 간선의 개수(M)
public static int start; // 시작 노드 번호(Start)
/* 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 */
public static List<List<QueueNode>> graph = new ArrayList<>();
public static List<List<QueueNode>> reverseGraph = new ArrayList<>();
/* 최단 거리 테이블 만들기 */
public static int[] d = new int[100001];
public static int[] rd = new int[100001];
public static void main(String[] args) {
// write your code here
_1238_파티 main = new _1238_파티();
main.solution();
}
public void solution() {
input();
/* 다익스트라 알고리즘을 수행 */
/** 1) 2번 노드 -> 다른 노드들에 대한 최단 거리 */
dijkstra(graph, d, start);
/** 2) 다른 노드 -> 2번 노드로 가는 최단 거리 */
dijkstra(reverseGraph, rd, start);
/* 합의 max 출력 */
Optional<Integer> max = IntStream.range(0, n + 1)
.filter(i -> d[i] != INF && rd[i] != INF)
.mapToObj(i -> d[i] + rd[i])
.max(Integer::compareTo);
System.out.println(max.get());
}
private static void dijkstra(List<List<QueueNode>> graph, int[] d, int start) {
/* 우선순위 큐 선언 */
PriorityQueue<QueueNode> pq = new PriorityQueue<>();
/* 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 */
pq.offer(new QueueNode(start, 0));
d[start] = 0;
/* 큐가 비어있지않을 때까지 반복 */
while(!pq.isEmpty()) {
/* 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 */
QueueNode node = pq.poll();
int dist = node.getDistance(); // 현재 노드까지의 비용
int now = node.getIndex(); // 현재 노드 번호
/* 현재 노드가 이미 처리된 적이 있는 노드라면 무시 */
if (d[now] < dist) {
continue;
}
/* 현재 노드와 연결된 다른 인접한 노드들을 확인 */
for (int i = 0; i < graph.get(now).size(); i++) {
/* 현재의 최단거리 + 현재의 연결된 노드의 비용 */
int cost = d[now] + graph.get(now).get(i).getDistance();
/* 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 */
if (cost < d[graph.get(now).get(i).getIndex()]) {
d[graph.get(now).get(i).getIndex()] = cost;
pq.offer(new QueueNode(graph.get(now).get(i).getIndex(), cost));
}
}
}
}
private static void input() {
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); // 노드의 개수(N)
m = sc.nextInt(); // 간선의 개수(M)
start = sc.nextInt(); // 시작 노드 번호(Start)
/* 그래프 초기화 */
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<QueueNode>());
reverseGraph.add(new ArrayList<QueueNode>());
}
/* 모든 간선 정보를 입력받기 */
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
/* a번 노드에서 b번 노드로 가는 비용이 c라는 의미 */
graph.get(a).add(new QueueNode(b, c));
reverseGraph.get(b).add(new QueueNode(a, c));
}
/* 최단 거리 테이블을 모두 무한으로 초기화 */
d = new int[n + 1];
rd = new int[n + 1];
Arrays.fill(d, INF);
Arrays.fill(rd, INF);
}
}
class QueueNode implements Comparable<QueueNode> {
private int index;
private int distance;
public QueueNode(int index, int distance) {
this.index = index;
this.distance = distance;
}
public int getIndex() {
return this.index;
}
public int getDistance() {
return this.distance;
}
// 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정
@Override
public int compareTo(QueueNode other) {
if (this.distance < other.distance) {
return -1;
}
return 1;
}
}
1) 문제 이해
기존 다익스트라 알고리즘의 문제와 다른 부분은 아래와 같다.
모든 학생들은 집에서 X에 갈수 있고, X에서 집으로 돌아올 수 있는 데이터만 입력으로 주어진다.
...
첫 번째 줄에 N명의 학생들 중 오고 가는데 가장 오래 걸리는 학생의 소요시간을 출력한다.
위 문제를 보고 시작 노드 X에서 다른 노드까지의 최단 거리와 추가로, 다른 노드에서 시작 노드 X까지의 최단 거리를 구해야함을 알아야한다.
1) X -> 다른 노드
2) 다른 노드 -> X
1)번과 2)번의 경우를 더한 값의 최댓값을 출력하면 된다.
2) 구현 코드
2가지를 구하기 위해 기존 다익스트라 알고리즘 코드에서 리스트와 dp 배열을 2개씩 생성했다.
/* 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 */
public static List<List<QueueNode>> graph = new ArrayList<>();
public static List<List<QueueNode>> reverseGraph = new ArrayList<>();
/* 최단 거리 테이블 만들기 */
public static int[] d = new int[100001];
public static int[] rd = new int[100001];
input() 에서도 2개씩 초기화하고 데이터를 담는다.
/* a번 노드에서 b번 노드로 가는 비용이 c라는 의미 */
graph.get(a).add(new QueueNode(b, c));
reverseGraph.get(b).add(new QueueNode(a, c));
/* 최단 거리 테이블을 모두 무한으로 초기화 */
d = new int[n + 1];
rd = new int[n + 1];
Arrays.fill(d, INF);
Arrays.fill(rd, INF);
dijkstra() 함수를 총 2번 호출한다.
public void solution() {
input();
/* 다익스트라 알고리즘을 수행 */
/** 1) 2번 노드 -> 다른 노드들에 대한 최단 거리 */
dijkstra(graph, d, start);
/** 2) 다른 노드 -> 2번 노드로 가는 최단 거리 */
dijkstra(reverseGraph, rd, start);
...
}
3) 결과 출력
/* 합의 max 출력 */
Optional<Integer> max = IntStream.range(0, n + 1)
.filter(i -> d[i] != INF && rd[i] != INF)
.mapToObj(i -> d[i] + rd[i])
.max(Integer::compareTo);
System.out.println(max.get());
반응형
'Algorithm > Problem Solving' 카테고리의 다른 글
[프로그래머스] Level2 42885번: 구명보트 (JAVA) (0) | 2022.03.25 |
---|---|
[프로그래머스] Level1 77484번: 로또의 최고 순위와 최저 순위 (JAVA) (0) | 2022.03.21 |
[Baekjoon 1439번] 뒤집기 문제 (with 자바) (0) | 2022.02.05 |
[이것이 코딩테스트다] 실전문제39. 화성탐사 (JAVA) (0) | 2022.01.17 |
[프로그래머스] Level2 60057번: 문자열 압축 (JAVA) (0) | 2022.01.17 |