[Algorithm] 다익스트라 알고리즘 / Dijkstra

2023. 8. 30. 23:00· Computer Science/Algorithm
목차
  1. 1. 다익스트라(Dijkstra) 란?
  2. 2. Default Logic
  3. 3. 시간복잡도
  4. 4. 추천 문제
728x90
반응형

1. 다익스트라(Dijkstra) 란?

  • 다익스트라 알고리즘이란 하나의 그래프에서의 최단 경로 탐색 알고리즘이며, 우리가 흔히 알고있는 동적계획법 즉 다이나믹 프로그래밍을 활용한 최단경로 탐색 알고리즘이다.
  • 한 정점에서 모든 정점까지의 최단거리를 구할 때 사용하며, 주어진 그래프중에서 음의 가중치가 없는 그래프에서 사용 가능하다. 음의 가중치가 있을 경우 벨만-포드 알고리즘을 사용하여 해결할 수 있다.

2. Default Logic

다익스트라 알고리즘 동작 반복 과정
1. 방문하지 않은 정점 중 가장 가중치 값이 작은 정점을 방문한다.
2. 현재 위치한 정점을 거쳐 다른 노드로 넘어가는 가중치 값을 계산하여 최소 비용을 갱신한다.
3. 위의 과정을 목표한 노드에 도달 할 때까지 반복한다.

이해를 돕기 위해 시각적으로 정리해 보았다.

시작 노드를 1번 노드, 목표한 도착노드를 4번 노드라고 가정한 후 진행할 것이다.

 

먼저 처음 시작할 때에는 거리 테이블을 엄청나게 큰 값 INF(Infinite) 무한대 값으로 초기화 한후 시작한다.

시작하는 노드인 1번 노드에 위치할 때 1번 노드의 가중치를 0으로 설정해주고 1과 근접해있는 노드들의 가중치를 확인해준다. 만약 주변의 노드의 가중치보다 (현재 노드의 가중치 + 인접 노드로 가는 가중치)가 더 작다면 priority_queue에 넣어준다. 지금 상태는 주변 인접노드들이 전부 INF값이기 때문에 다 들어간다.

대신 가중치에 -를 붙혀 오름차순으로 정리해 준다.

가장 인접한 2번, 4번, 5번 노드의 가중치를 확인했을 때 2번 노드로 가는 가중치가 가장 적기 때문에 2번 노드에 방문한다.

2번 노드에 도착한 후 2번 노드와 인접한 노드인 3번 5번 노드를 탐색한다. 3번노드로 가는 방법의 가중치는 1번에서 2번을 가는 가중치에 2번에서 3번을 가는 가중치를 거쳐야하기 때문에 5고 현재 3번 노드의 가중치는 INF이기 때문에 이또한 priority_queue에 넣어준다. 5번 노드로 가는 방법은 1 > 2 + 2 > 5 이기 때문에 가중치가 3이지만 1에서 5번 노드로 가는 방법이 가중치 2로 존재하기 때문에 넣지 않는다.

 

똑같이 가중치가 가장 낮은 5번노드로 이동후 방문하지 않은 간선을 확인한다. 4번노드로 이동하는 간선의 가중치를 확인 했을 때 1 > 5 > 4로 가는 방법은 3의 가중치를 가지고 1 > 4로 가는 방법은 4의 가중치를 가지기 때문에 더 작은 값인 1 > 5 > 1로 가는 방법을 pq에 넣게 된다.

 

우리가 목표한 노드는 4번 노드인데 priority_queue에 보면 cur이라는 값에 4번 노드를 가진 값이 두개가 들어있다. 가장 가중치가 작은 top에 위치한 순서를 수행하게 되면 그 뒤에 있는 가중치 4짜리는 저절로 가지치기 당하게 된다.

이렇게 해서 모든 한 점에서 시작하여 모든 인접한 간선을 조사한 후 가장 최단경로로 갈 수 있는 경우의 수를 조사하는 알고리즘이 다익스트라 알고리즘이다.

 

백준에 있는 다익스트라 알고리즘을 활용하여 푸는 문제 중 1753번 최단경로 라는 문제의 정답을 약간 변형해서 가져왔다.

대표적인 다익스트라 문제이며 가장 스탠다드한 풀이이다.

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f; // 시작 노드에서 해당 노드까지의 경로가 없는 경우의 비용
#define MAX_VERTEX 1001 // 최대 vertex 개수
#define MAX_EDGE 1001 // 최대 edge 개수
int v, e, start_node;
//최소 비용 배열
int d[MAX_VERTEX];
//간선 정보를 담은 vector
//index : 시작노드
//value : pair<비용, 도착 노드> 목록
vector<pair<int, int>> edge[MAX_EDGE];
void dijkstra(int start_node) {
//시작 노드에서 시작 노드로 가는 비용은 0
d[start_node] = 0;
//시작 노드부터 어떤 도착 노드까지의 최소 비용을 제시하는 간선 목록
//pair<비용, 도착 노드> 형식의 우선순위 큐이다.
priority_queue<pair<int, int>> pq;
//시작 노드에서 시작 노드로 가는 경로와 비용을 pq에 삽입;
pq.push({0, start_node});
//pq의 모든 경로를 확인할 때 까지 반복
while(!pq.empty()) {
int cur = pq.top().second;
int cost = -pq.top().first; //오름차순 정렬을 위해 -를 붙혀서 넣어줬기 때문에 다시 원래값으로 돌림
pq.pop();
if(d[cur] < cost) {
continue;
}
for(int i = 0; i < edge[cur].size(); ++i) {
int next = edge[cur][i].second;
int nextCost = cost + edge[cur][i].first;
if(d[next] > nextCost) {
d[next] = nextCost;
pq.push({-nextCost, next}); //오름차순 정렬을 위해 -를 붙혀서 넣어줌
}
}
}
}
int main() {
cin >> v >> e;
cin >> start_node;
for(int i = 1; i <= v; i++) {
d[i] = INF;
}
while(e--) {
int start, end, cost;
cin >> start >> end >> cost;
edge[start].push_back({cost, end});
}
dijkstra(start_node);
for(int i = 1; i < v + 1; ++i) {
if(d[i] == INF) {
cout << "INF" << "\n";
}
else {
cout << d[i] << "\n";
}
}
}

3. 시간복잡도

간선의 수를 E(Edge), 노드의 수를 V(Vertex)라고 했을 때 O(E logV)가 된다.
우선순위 큐에서 꺼낸 노드는 서로 인접한 노드만 탐색하므로 최악의 경우라도 총 간선 수인 E만큼만 반복한다. 즉 하나의 간선에 대해서는 O(logE)이고, E는 V2보다 항상 작기 때문에 E개의 간선을 우선순위 큐에 넣었다 빼는 최악의 경우에 대해서는 O(E logV)가 된다.

4. 추천 문제

더보기

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

 


 

728x90
반응형

'Computer Science > Algorithm' 카테고리의 다른 글

[Algorithm] 유니온 파인드 / Union-Find  (0) 2023.10.01
[Algorithm] 이분탐색 / Binary Search  (0) 2023.09.25
[Algorithm] 위상정렬 / Topological Sort  (0) 2023.09.22
[Algorithm] 투포인터 / Two Pointers  (0) 2023.08.21
[Algorithm] 동적 계획법 / Dynamic Programming  (0) 2023.06.19
  1. 1. 다익스트라(Dijkstra) 란?
  2. 2. Default Logic
  3. 3. 시간복잡도
  4. 4. 추천 문제
'Computer Science/Algorithm' 카테고리의 다른 글
  • [Algorithm] 이분탐색 / Binary Search
  • [Algorithm] 위상정렬 / Topological Sort
  • [Algorithm] 투포인터 / Two Pointers
  • [Algorithm] 동적 계획법 / Dynamic Programming
보글보글소다
보글보글소다
Conquer Mind, Conquer All보글보글소다 님의 블로그입니다.
반응형
보글보글소다
Conquer Mind, Conquer All
보글보글소다
전체
오늘
어제
  • 분류 전체보기
    • Algorithm
      • Beakjoon
      • Programmers
    • Frontend
      • React.js
      • JavaScript
    • Backend
      • Java
      • Spring
      • Node.js
    • Design Pattern
    • Computer Science
      • Algorithm
      • 컴퓨터구조
      • 운영체제
      • 네트워크
      • 데이터베이스
      • 자료구조
    • Projects
      • 식단 짜주는 웹
    • 정보보호병
      • Study In military
      • 정보보호병
    • 인공지능
      • 논문 리뷰

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 관리
  • 글쓰기

공지사항

인기 글

태그

  • 운영체제
  • BaekJoon
  • 스프링
  • 알고리즘 풀이
  • BFS
  • Programmers
  • 자료구조
  • 그래프
  • 동적계획법
  • 프로그래머스
  • 알고리즘
  • 백엔드
  • 백준
  • spring
  • 코딩테스트
  • 이분탐색
  • DP
  • 구현
  • Algorithm
  • 백준 풀이

최근 댓글

최근 글

250x250
hELLO · Designed By 정상우.v4.2.2
보글보글소다
[Algorithm] 다익스트라 알고리즘 / Dijkstra
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.