문제를 잘 푸는 건 아니지만 BFS, DFS, Brute-force, DP, Greedy, 구현 등 여러 알고리즘을 어느 정도 이해하고 있다는 생각이 들었다. 그런데 문제를 풀다보면 왕왕 등장해서 나를 당황시켰던 알고리즘이 바로 최단 경로 알고리즘이다. 마주치면 그냥 모른 척 지나갔는데 항상 찜찜했다.
찜찜한 마음에 친구에게 물어보면 맨날 이런 식이었다.
나: 다익스트라가 뭐예요?
친구: 최단경로 찾는 거요
나: ..? (어쩔티비)
그래서 최단 경로를 제대로 알고 나면 후련할 것 같아서 정리한다.
이번 기회에 깊이 공부해보자!
가중치가 있는 경우 최단 경로를 구하는 알고리즘에는 대표적으로 두 가지가 있다.
임의의 정점에서 모든 정점까지의 최단경로를 구하는 다익스트라 (제일 유명)
모든 정점에서 다른 모든 정점까지의 최단경로를 구하는 플로이드-워셜
이외에도 벨만-포드가 있다는데 이건 나중에 기회되면 해보는 걸로
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Dijkstra {
static int v, e, start;
static int[] dist;
static ArrayList<ArrayList<Node>> graph;
static class Node {
int idx;
int cost;
Node(int idx, int cost) {
this.idx = idx;
this.cost = cost;
}
}
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());
dist = new int[v + 1];
graph = new ArrayList<>();
for(int i = 0; i < v+1; i++) {
graph.add(new ArrayList<>());
}
for(int i = 0; i < e; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
graph.get(a).add(new Node(b, c));
}
for(int i = 0; i < v+1; i++) {
dist[i] = Integer.MAX_VALUE;
}
PriorityQueue<Node> q = new PriorityQueue<>((o1, o2) -> Integer.compare(o1.cost, o2.cost));
q.offer(new Node(start, 0));
dist[start] = 0;
while (!q.isEmpty()) {
Node curNode = q.poll();
if(dist[curNode.idx] < curNode.cost) continue;
for(int i = 0; i < graph.get(curNode.idx).size(); i++) {
Node nNode = graph.get(curNode.idx).get(i);
if(curNode.cost + nNode.cost < dist[nNode.idx]) {
dist[nNode.idx] = curNode.cost + nNode.cost;
q.offer(new Node(nNode.idx, dist[nNode.idx]));
}
}
}
System.out.println(Arrays.toString(dist));
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Floydwarshall {
static int n, m;
static int[][] dist;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
m = Integer.parseInt(br.readLine());
dist = new int[n][n];
// 테이블 초기화
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i == j) {
dist[i][j] = 0;
continue;
}
dist[i][j] = 1000000000;
}
}
// 간선 거리 저장
for(int i = 0; i < m; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
dist[a][b] = Math.min(dist[a][b], d);
dist[b][a] = Math.min(dist[b][a], d);
}
for(int k = 0; k < n; k++) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++) {
System.out.print(dist[i][j] + " ");
}
System.out.println("");
}
}
}