Company
교육 철학

다익스트라 알고리즘

다익스트라 알고리즘 (Dijkstra's Algorithm)

핵심 개념

재귀호출을 사용하지 않고 최단거리(최소비용) 구하는 알고리즘
최단거리 알고리즘들은 네트워크, 게임에서도 사용된다.

실생활 활용 예시

지하철 노선도 프로그램에서 최단경로를 찾는다던지
네트워크 사용 할때 최단경로로 연결을 구해야 한다던지
게임에서 캐릭터의 길찾기 알고리즘으로도 사용이 가능하다

문제 예시

A에서 C까지 가는 최소 비용은?

A → D → B → C로 가면 총 35만원에 갈 수 있다.
그래프 구조: B (5만원) 50↗ ↘5 A 10 C 20↘ ↗25 D A→C 직접: 999999 (불가능) A→D→B→C: 20 + 10 + 5 = 35만원 ✅ (최적)
Plain Text
복사
다익스트라 알고리즘을 통해서 A에서 출발해서 모든 도착지점의 최단경로를 구 할 수 있다.

다익스트라 알고리즘 동작 원리

문제를 보면서 알아보자
A에서 C까지 가는 최소 비용은?
A → D → B → C로 가면 총 35만원에 갈 수 있다.
다익스트라 알고리즘을 통해서 A에서 출발해서 모든 도착지점의 최단경로를 구 할수 있다.
다음과 같은 규칙을 반복적으로 실행하면 최소비용을 구할 수 있다.
1.
가장 저렴하게 갈 수 있는 곳을 경유지로 선택한다.
2.
선택된 경유지를 거쳐 다른 곳으로 이동 할 때, 더 저렴한지 확인한다.
3.
더 저렴하다면, 최소비용 전광판에 갱신한다.
경유지로 한번 선택이 되었다면, 중복 방문체크를 위해서 배열에 체크해준다.
방문하지 않은 곳에서 가장 싼 값을 선택한다.
A에서 출발해서 D까지 가는 최소거리는 20이다.
D에서 들렸다가 다른지역 (A,B,C) 가는 비용
vs
전광판에 써있는 다른지역 (A,B,C)가는 비용
D에 들렸다가 B로 가는 비용 20 + 10 = 30
전광판에 써있는 B까지 가는비용은 50 이므로 전광판을 A→D→B = 30으로 수전한다.
A에서 D를 들렸다가 C로 가는 비용은 20 + 25 = 45 이고
바로 A→C로가는 비용은 99999 이므로 값을 수정해준다. 더 싼 값으로
그러면 이제 D 를 거쳐서 가는 역할은 끝났다. D는 방문한곳으로 체크해준다. 중복 경유지를 제거해주기 위해서
이제 새로운 경유지를 통해서 다른 노드들의 비용을 계산하여 다시 비교해보자
방문하지 않은곳 B를 들렸다가 C를 가는데 비용은
이미기록해둔 B경로값(30) + 5 = 35 이고 전광판에 써있는 C를 가는 비용은 45인데 이것보다 작으니 갱신해준다.
이런 과정을 반복하면 최정족으로 A>B : 30만원 A >C : 35만원 A>D 20
이렇게 최소비용을 구할 수 있다.

다익스트라 알고리즘 완전 구현

#include <iostream> #define NOT 999999 int map[4][4] = { {0, 50, NOT, 20 }, // A에서 각 노드까지 {NOT, 0, 5, NOT}, // B에서 각 노드까지 {NOT, NOT, 0, NOT}, // C에서 각 노드까지 {NOT, 10, 25, 0 } // D에서 각 노드까지 }; int result[4] = {0, 50, NOT, 20}; // 최소비용 테이블 int visited[4] = {1, 0, 0, 0}; // 방문 여부 (A는 시작점이므로 방문됨) // 방문하지 않은 노드 중 최소 비용 노드 찾기 int findMin() { int min = 987654321; int minIndex = -1; for (int i = 0; i < 4; i++) { if (visited[i] == 0 && result[i] < min) { min = result[i]; minIndex = i; } } return minIndex; } void dijkstra() { int minIndex = 0; for (int i = 0; i < 3; i++) // 3번 반복 (시작점 제외한 나머지 노드) { // 1. via가 0인 곳 중에 최소값을 찾기 minIndex = findMin(); // 2. a vs b 해서 a가 더 저렴하면 전광판에 갱신해준다. // a = 경유지까지 가는 비용 + 경유지에서 목적지까지 가는 비용 // b = A에서 목적지까지 가는 비용 for (int j = 0; j < 4; j++) { int a = result[minIndex] + map[minIndex][j]; // 경유 비용 int b = result[j]; // 직행 비용 if (a < b) { result[j] = a; // 더 저렴하면 갱신 } } visited[minIndex] = 1; // 해당 노드 방문 완료 } // 결과 출력 std::cout << "=== 최단 거리 결과 ===" << std::endl; char nodes[] = {'A', 'B', 'C', 'D'}; for (int i = 0; i < 4; i++) { std::cout << "A → " << nodes[i] << ": " << result[i] << "만원" << std::endl; } } int main() // char main()에서 int main()으로 수정 { dijkstra(); return 0; }
C++
복사

알고리즘 핵심 로직 분석

1. findMin() 함수

// 방문하지 않은 노드 중 최소 비용 노드 찾기 int findMin() { int min = 987654321; int minIndex = -1; for (int i = 0; i < 4; i++) { if (visited[i] == 0 && result[i] < min) { min = result[i]; minIndex = i; } } return minIndex; }
C++
복사

2. 거리 갱신 로직

// 경유지를 통한 비용 vs 직행 비용 비교 int a = result[minIndex] + map[minIndex][j]; // 경유 비용 int b = result[j]; // 현재 최소 비용 if (a < b) { result[j] = a; // 더 저렴하면 갱신 }
C++
복사

시간복잡도

기본 다익스트라

시간복잡도: O(V²) - V는 정점의 개수
공간복잡도: O(V)

우선순위 큐 사용시

#include <queue> #include <vector> void dijkstra_optimized(int start) { vector<int> dist(V, INF); priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq; dist[start] = 0; pq.push({0, start}); while (!pq.empty()) { int cost = pq.top().first; int here = pq.top().second; pq.pop(); if (dist[here] < cost) continue; for (auto& edge : graph[here]) { int there = edge.first; int nextDist = cost + edge.second; if (nextDist < dist[there]) { dist[there] = nextDist; pq.push({nextDist, there}); } } } }
C++
복사
시간복잡도: O((V + E) log V) - 더 효율적

다익스트라 vs 다른 최단경로 알고리즘

알고리즘
시간복잡도
음수 가중치
모든 쌍 최단경로
다익스트라
O(V²) 또는 O((V+E)logV)
(단일 출발점)
벨만-포드
O(VE)
(단일 출발점)
플로이드-워셜
O(V³)

실전 활용 예제

1. 네비게이션 시스템

// 도로망에서 최단 경로 찾기 struct Road { int to; int distance; int time; }; void findShortestRoute(int start, int destination) { // 다익스트라로 최단 경로 계산 }
C++
복사

2. 네트워크 라우팅

// 패킷이 가장 빠른 경로로 전송되도록 void findOptimalRoute(int source, int target) { // 지연시간을 가중치로 하여 최적 경로 계산 }
C++
복사

3. 게임 AI 길찾기

// 캐릭터가 장애물을 피해 목적지까지 void findPath(Point start, Point goal) { // 맵을 그래프로 변환하여 최단 경로 계산 }
C++
복사

주의사항

1. 음수 가중치 불가

다익스트라는 음수 가중치를 처리할 수 없습니다. 음수 가중치가 있다면 벨만-포드 알고리즘 사용!
Plain Text
복사

2. 그래프 표현

// 인접 행렬 vs 인접 리스트 int matrix[V][V]; // 메모리: O(V²), 밀집 그래프에 적합 vector<vector<pair<int,int>>> adj; // 메모리: O(V+E), 희소 그래프에 적합
C++
복사

3. 무한대 표현

#define INF 987654321 // 충분히 큰 값으로 설정 // 또는 #define INF INT_MAX 사용 (오버플로우 주의)
C++
복사

핵심 정리

다익스트라 알고리즘

1.
탐욕적 접근: 매번 최소 비용 노드 선택
2.
단일 출발점: 한 점에서 모든 점까지의 최단거리
3.
양수 가중치: 음수 가중치는 처리 불가
4.
실용적: 실제 최단경로 문제에 가장 많이 사용

핵심 단계

1.
초기화: 시작점 0, 나머지 무한대
2.
선택: 방문하지 않은 최소 비용 노드
3.
갱신: 선택된 노드를 통한 경로가 더 짧으면 갱신
4.
반복: 모든 노드 방문할 때까지
"가장 가까운 곳부터 차례대로 방문하며 최단거리를 확정짓는 알고리즘"

“강의는 많은데, 왜 나는 아직도 코드를 못 짤까?”

혼자 공부하다 보면 누구나 이런 고민을 하게 됩니다.
강의는 다 들었지만 막상 손이 안 움직이고,
복습을 하려 해도 무엇을 다시 봐야 할지 모르겠고,
질문할 곳도 없고,
유튜브는 결국 정답을 따라 치는 것밖에 안 되는 것 같고.
문제는 ‘연습’이 빠졌기 때문입니다.
단순히 강의를 듣는 것만으로는 실력이 늘지 않습니다.
실제 문제를 풀고, 고민하고, 직접 구현해보는 시간이 반드시 필요합니다.

그래서, 얌얌코딩 코칭은 다릅니다.

그냥 가르치지 않습니다.
스스로 설계하고, 코딩할 수 있게 만듭니다.
얌얌코딩 코칭에서는 단순한 예제가 아닌,
스스로 문제를 분석하고 구현해야 하는 연습문제를 제공합니다.
이 연습문제들은 다음과 같은 역량을 키우기 위해 설계되어 있습니다:
문제를 스스로 쪼개고 설계하는 힘
다양한 조건을 만족시키는 실제 구현 능력
기능 단위가 아닌, 프로그램 단위로 사고하는 습관
마침내 자신의 힘으로 코드를 끝까지 작성하는 경험

지금 필요한 건 더 많은 강의가 아닙니다.

코드를 스스로 완성해 나가는 훈련,
그것이 지금 실력을 끌어올릴 가장 현실적인 방법입니다.
자세한 안내 보기: 프리미엄 코칭 안내 바로가기
또는 카카오톡 상담방: 얌얌코딩 상담방