PS/Algorithms
[Java] Dijkstra algorithm - (그래프)간선 가중치가 양수
CalicoCat22
2022. 1. 8. 14:15
https://blog.naver.com/ndb796/221234424646
23. 다익스트라(Dijkstra) 알고리즘
다익스트라(Dijkstra) 알고리즘은 다이나믹 프로그래밍을 활용한 대표적인 최단 경로(Shortest Path) 탐...
blog.naver.com
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
O((V+E)logV)
간선 가중치가 음수일 때는 사용할 수 없다.
시작점 k에서 각 정점으로의 거리를 int[] 선언하고, 간선으로 이어진 정점만 거리를 갱신한다.(멀면 INF)
반복해서 가장 가까운 정점을 탐색하고
그 정점에 이어진 정점들로의 거리를 계속해 갱신한다.
1) nlgn (아직 명확히 안외워짐)
import java.util.*;
import java.io.*;
public class dijkstra_nlgn{
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int INF = 999999;
public static void main(String[] args){
int n = fs.nextInt(), v = fs.nextInt(), k = fs.nextInt();
// n : 노드의 개수
// v : 간선의 개수
// k : 시작점
List<List<Node>> list = new ArrayList<>();
for (int i=0;i<=n;i++) list.add(new ArrayList<>());
for (int i=0;i<v;i++){
int from = fs.nextInt(), to = fs.nextInt(), wei = fs.nextInt();
list.get(from).add(new Node(to, wei));
}
PriorityQueue<Node> q = new PriorityQueue<>((o1, o2) -> Integer.compare(o1.weight, o2.weight));
q.add(new Node(k, 0));
int[] dist = new int[n+1];
for (int i=0;i<=n;i++) dist[i] = INF;
dist[k] = 0;
while (!q.isEmpty()){
Node curNode = q.poll();
if (dist[curNode.index] < curNode.weight){
continue;
}
for (int i=0;i<list.get(curNode.index).size();i++){
Node nextNode = list.get(curNode.index).get(i);
if (curNode.weight + nextNode.weight < dist[nextNode.index]){
dist[nextNode.index] = curNode.weight + nextNode.weight;
q.add(new Node(nextNode.index, dist[nextNode.index]));
}
}
}
for (int i=1;i<=n;i++){
if (dist[i] == INF) pw.println("INF");
else pw.println(dist[i]);
}
pw.close();
}
static class Node {
int index, weight;
public Node(int index, int weight){
this.index = index;
this.weight = weight;
}
}
// ----------input function----------
static void sort(int[] a){
ArrayList<Integer> L = new ArrayList<>();
for (int i : a) L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++) a[i] = L.get(i);
}
static class FastScanner{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next(){
while (!st.hasMoreTokens()){
try{
st = new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt(){
return Integer.parseInt(next());
}
int[] readArray(int n){
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
long nextLong(){
return Long.parseLong(next());
}
}
}
2) n^2 (이건 확실히 외웠는데 가끔 tle mle 떠서...)
import java.util.*;
import java.io.*;
public class dijkstra_n2{
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int n, m, x, INF = 10000000;
public static void main(String[] args){
n = fs.nextInt();
m = fs.nextInt();
x = fs.nextInt();
// n:노드 개수 / m:간선 개수 / x:시작점
int[][] map1 = new int[n+1][n+1];
for (int[] a : map1){
Arrays.fill(a, INF);
}
for (int i=1;i<=n;i++){
map1[i][i] = 0;
}
for (int i=0;i<m;i++){
int start = fs.nextInt(), end = fs.nextInt(), wei = fs.nextInt();
map1[start][end] = wei;
}
// int[] pp = dijk(map1);
// pp : x에서 1~n번 노드까지의 최단 거리
pw.close();
}
static int[] dijk(int[][] dis, int start){
int[] d = new int[n+1];
boolean[] v = new boolean[n+1];
v[start] = true;
for (int i=1;i<=n;i++){
d[i] = dis[start][i];
}
for (int i=0;i<n-2;i++){
int next = findIndex(d, v);
v[next] = true;
for (int j=1;j<=n;j++){
if (!v[j] && d[next] + dis[next][j] < d[j]){
d[j] = d[next] + dis[next][j];
}
}
}
return d;
}
static int findIndex(int[] d, boolean[] v){
int min = INF;
int index = 0;
for (int i=1;i<=n;i++){
if (!v[i] && d[i] < min){
min = d[i];
index = i;
}
}
return index;
}
// ----------input function----------
static void sort(int[] a){
ArrayList<Integer> L = new ArrayList<>();
for (int i : a) L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++) a[i] = L.get(i);
}
static class FastScanner{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next(){
while (!st.hasMoreTokens()){
try{
st = new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt(){
return Integer.parseInt(next());
}
int[] readArray(int n){
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
long nextLong(){
return Long.parseLong(next());
}
}
}