Skip to content

Commit 7c7e860

Browse files
authored
Create DijkstraPath.cpp
1 parent 5cc38ae commit 7c7e860

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

Algorithm/DijkstraPath.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std;
4+
5+
using pii = pair<int, int>;
6+
7+
class Graph {
8+
public:
9+
int n;
10+
// 인접 정점
11+
// first: 정점, second: 가중치
12+
vector<pii>* adj;
13+
14+
Graph(int n) {
15+
this->n = n;
16+
adj = new vector<pii>[n];
17+
}
18+
19+
// 간선 추가
20+
void insertEdge(int u, int v, int w) {
21+
this->adj[u].push_back(make_pair(v, w));
22+
this->adj[v].push_back(make_pair(u, w));
23+
}
24+
};
25+
26+
class Compare {
27+
public:
28+
// 우선순위 큐를 위한 비교 함수
29+
bool operator() (pii a, pii b) {
30+
return a.second > b.second;
31+
}
32+
};
33+
34+
vector<int>* dijkstra(Graph* g, int start) {
35+
// 최단 거리가 발견되면 true
36+
vector<bool> found(g->n, false);
37+
38+
// 해당 정점까지의 거리 (default : 무한)
39+
vector<int> distance(g->n, INT_MAX);
40+
41+
// 최단거리가 업데이트 될때 바로 이전에 방문하게 되는 정점
42+
vector<int>* from = new vector<int>(g->n);
43+
44+
// 가장 가까운 정점을 찾기 위한 우선순위 큐
45+
// first: 정점 번호, second: 정점까지의 거리
46+
priority_queue<pii, vector<pii>, Compare> pq;
47+
48+
// 출발지의 최단거리 발견
49+
found[start] = true;
50+
// 출발지까지 거리 0
51+
distance[start] = 0;
52+
53+
// 우선순위 큐에 넣는다.
54+
pq.push(make_pair(start, 0));
55+
56+
for (int i = 0; i < g->n; i++) {
57+
// 가장 가까운 정점을 우선순위 큐에서 꺼낸다.
58+
int u = pq.top().first;
59+
pq.pop();
60+
61+
// 최단거리 발견
62+
found[u] = true;
63+
for (int j = 0; j < g->adj[u].size(); j++) {
64+
// 정점 u의 인접정점의 최단거리 업데이트
65+
pii v = g->adj[u][j];
66+
67+
if (!found[v.first]) {
68+
if (distance[u] + v.second < distance[v.first]) {
69+
distance[v.first] = distance[u] + v.second;
70+
(*from)[v.first] = u;
71+
72+
// 우선순위 큐에 추가
73+
pq.push(make_pair(v.first, distance[v.first]));
74+
}
75+
}
76+
}
77+
}
78+
79+
return from;
80+
}
81+
82+
// from[n]에서 목적지까지의 정점을 재귀적으로 출력한다.
83+
void trace_path(int s, int e, vector<int>* from) {
84+
// 기저 조건 : 시작점과 목적지가 같은 경우
85+
if ((*from)[e] == s) {
86+
cout << s << " -> ";
87+
return;
88+
89+
}
90+
91+
// 재귀호출을 통해 정점 e전의 정점에 대한 경로를 출력한다..
92+
trace_path(s, (*from)[e], from);
93+
94+
// 최단경로에서 정점 e 바로 이전의 정점를 화면에 출력한다.
95+
cout << (*from)[e] << " - > ";
96+
}
97+
98+
// 마지막 목적지를 간편하게 화면의 출력하기 위해 함수 분리
99+
void print_path(int s, int e, vector<int>* from) {
100+
// 위의 trace_path를 호출하여 최단 경로를 출력한후,
101+
trace_path(s, e, from);
102+
103+
// 목적지의 정점 번호도 출력한다.
104+
cout << e;
105+
}
106+
107+
108+
int main(void) {
109+
Graph* g = new Graph(7);
110+
g->insertEdge(0, 1, 7);
111+
g->insertEdge(1, 0, 7);
112+
g->insertEdge(0, 4, 3);
113+
g->insertEdge(4, 0, 3);
114+
g->insertEdge(0, 5, 10);
115+
g->insertEdge(5, 0, 10);
116+
g->insertEdge(1, 4, 2);
117+
g->insertEdge(4, 1, 2);
118+
g->insertEdge(1, 5, 6);
119+
g->insertEdge(5, 1, 6);
120+
g->insertEdge(1, 2, 4);
121+
g->insertEdge(2, 1, 4);
122+
g->insertEdge(1, 3, 10);
123+
g->insertEdge(3, 1, 10);
124+
g->insertEdge(2, 3, 2);
125+
g->insertEdge(3, 2, 2);
126+
g->insertEdge(4, 3, 11);
127+
g->insertEdge(3, 4, 11);
128+
g->insertEdge(4, 6, 5);
129+
g->insertEdge(6, 4, 5);
130+
g->insertEdge(6, 3, 4);
131+
g->insertEdge(3, 6, 4);
132+
g->insertEdge(3, 5, 9);
133+
g->insertEdge(5, 3, 9);
134+
135+
136+
// 최단 경로를 구한다.
137+
auto from = dijkstra(g, 0);
138+
139+
// 0부터 각 정점까지의 경로 출력
140+
for (int i = 0; i < g->n; i++) {
141+
print_path(0, i, from);
142+
cout << "\n";
143+
}
144+
145+
return 0;
146+
}

0 commit comments

Comments
 (0)