알고리즘
[백준 1753] 최단경로 (다익스트라 알고리즘) - 자바(JAVA)
사랑박
2023. 10. 11. 14:03
1. 문제
https://www.acmicpc.net/problem/1753
1753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가
www.acmicpc.net
2. 풀이
방향그래프가 주어질 때 한 시작점에서 다른 모든 정점으로의 최댄 경로를 구하는 문제이다.
다익스트라 알고리즘으로 문제를 풀 수 있다. 다익스트라 알고리즘은 PriorityQueue를 사용한다 !
3. 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int V,E, start;
static int[] dis;
static boolean[] visit;
static ArrayList<Edge>[] adj;
static class Edge{
int v; // 도착 정점
int c; // 비용
public Edge(int v,int c){
this.v=v;
this.c=c;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(br.readLine());
V=Integer.parseInt(st.nextToken()); // 정점개수
E=Integer.parseInt(st.nextToken()); // 간선개수
start=Integer.parseInt(br.readLine()); // 시작 위치
// 간선 입력 받기 + 인접 리스트
adj=new ArrayList[V+1];
for(int i=0;i<=V;i++){
adj[i]=new ArrayList<Edge>();
}
for(int i=0;i<E;i++){
st=new StringTokenizer(br.readLine());
int s=Integer.parseInt(st.nextToken());
int e=Integer.parseInt(st.nextToken());
int c=Integer.parseInt(st.nextToken());
adj[s].add(new Edge(e,c));
}
// 경로 비용 저장하는 배열 - 무한대로 초기화
dis=new int[V+1];
for(int i=1;i<=V;i++){
dis[i]=Integer.MAX_VALUE;
}
visit=new boolean[V+1];
// 다익스트라
dijkstra();
// 정답 출력
StringBuilder sb=new StringBuilder();
for(int i=1;i<=V;i++){
if(dis[i]==Integer.MAX_VALUE){
sb.append("INF");
}else {
sb.append(dis[i]);
}
sb.append("\n");
}
System.out.println(sb);
}
public static void dijkstra(){
// Comparator : 람다 -> 가중치 작은 순서로 정렬
PriorityQueue<Edge> pq=new PriorityQueue<>((o1, o2) -> o1.c - o2.c);
dis[start]=0;
pq.offer(new Edge(start,0));
while(!pq.isEmpty()){
Edge now=pq.poll();
if(visit[now.v])
continue;
visit[now.v]=true;
for(Edge e : adj[now.v]){ // 현재 정점에서 갈 수 있는 정점&비용 탐색
if(!visit[e.v] && dis[now.v] + e.c < dis[e.v]){ // 최소 비용으로 방문
dis[e.v]=dis[now.v]+e.c;
pq.offer(new Edge(e.v, dis[e.v]));
}
}
}
}
}