알고리즘
최단 경로 - 다익스트라 알고리즘
leeeehhjj
2022. 6. 27. 15:38
다익스트라 알고리즘
: 특정 노드에서 다른 노드로 가는 각각의 최단 경로를 구해주는 알고리즘(음의 간선이 없을 때 제대로 동작)
1. 출발 노드를 설정한다
2. 최단 거리 테이블을 초기화 한다
3. 방문하지 않은 노드 중 거리가 가장 짧은 노드를 선택한다
4. 해당 노드를 거쳐 다른 노드로 가는 비용을 계산해 최단 거리 테이블을 갱신한다
5. 3과 4번을 반복한다
-출발 노드는 1일 때
노드 번호 | 1 | 2 | 3 | 4 | 5 | 6 |
거리 | 0 | 무한 | 무한 | 무한 | 무한 | 무한 |
-1번 노드에서 갈 수 있는 노드는 2,3,4이므로 이 노드들의 최단 거리 테이블을 갱신
노드 번호 | 1 | 2 | 3 | 4 | 5 | 6 |
거리 | 0 | 2 | 5 | 1 | 무한 | 무한 |
-4번 노드가 가장 가까우므로 4번 노드를 거쳐 가는 거리 확인 -> 3번, 5번으로 가는 거리의 최단 거리 갱신
노드 번호 | 1 | 2 | 3 | 4 | 5 | 6 |
거리 | 0 | 2 | 1+3 | 1 | 1+1 | 무한 |
-2번과 5번 노드로 가는 거리가 가장 짧으므로 숫자가 작은 2번 노드로 가는 길을 선택 후 2번 노드를 거쳐 가는 거리 확인
-> 현재 거리보다 더 짧게 가는 방법 없으므로 갱신x
5번 노드를 거쳐가는 거리 확인
-> 3번과 6번으로 가는 최단 거리 갱신
노드 번호 | 1 | 2 | 3 | 4 | 5 | 6 |
거리 | 0 | 2 | 1+1+1 | 1 | 2 | 1+1+2 |
- 3번 노드를 선택한 뒤 테이블 갱신
- 6번 노드 선택 후 갱신
간단한 다익스트라 알고리즘(O(V^2)) - v는 노드 개수
: 방문하지 않은 노드 중 최단 거리가 가장 짧은 노드 선택위해 1차원 리스트의 모든 원소를 탐색
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
class Node {
private int index;
private int distance;
public Node(int index, int distance) {
this.index = index;
this.distance = distance;
}
public int getIndex() {
return this.index;
}
public int getDistance() {
return distance;
}
}
public class Main {
static final int INF = (int)1e9; //무한 의미하는 10억
static int n,m,start;
static ArrayList<ArrayList<Node>> graph = new ArrayList<ArrayList<Node>>();
static boolean[] visited = new boolean[100001];
static int[] table = new int[100001];
// 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환
public static int getSmallestNode() {
int min = INF;
int index = 0;
for (int i = 1; i <= n; i++) {
if (table[i] < min && !visited[i]) {
min = table[i];
index = i;
}
}
return index;
}
static void dijkstra(int start) {
table[start] = 0;
visited[start] = true;
for (int i = 0; i < graph.get(start).size(); i++) {
table[graph.get(start).get(i).getIndex()] = graph.get(start).get(i).getDistance();
}
for (int i = 0; i < n-1; i++) {
int now = getSmallestNode();
visited[now] = true;
for (int j = 0; j < graph.get(now).size(); j++) {
int cost = table[now] + graph.get(now).get(j).getDistance();
if (cost < table[graph.get(now).get(j).getIndex()])
table[graph.get(now).get(j).getIndex()] = cost;
}
}
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
n= sc.nextInt();
m = sc.nextInt();
start = sc.nextInt();
//그래프 초기화
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<Node>());
}
// 모든 간선 정보를 입력받기
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 Node(b, c));
}
// 최단 거리 테이블을 모두 무한으로 초기화
Arrays.fill(table, INF);
// 다익스트라 알고리즘을 수행
dijkstra(start);
// 모든 노드로 가기 위한 최단 거리를 출력
for (int i = 1; i <= n; i++) {
// 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
if (table[i] == INF) {
System.out.println("INFINITY");
}
// 도달할 수 있는 경우 거리를 출력
else {
System.out.println(table[i]);
}
}
}
}
참고
이것이 취업을 위한 코딩 테스트다 with 파이썬