Skip to content

Commit 931d031

Browse files
committed
거의 최단경로
1 parent 7e82f25 commit 931d031

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <cstring>
5+
using namespace std;
6+
7+
#define MAX_N 500
8+
#define INF 1e9
9+
10+
int n, m;
11+
vector<pair<int, int>> edges[MAX_N]; //각 노드 사이의 거리를 담는 배열
12+
vector<pair<int, int>> trace[MAX_N]; //BFS의 역추적을 위한 배열
13+
bool visited[MAX_N][MAX_N];
14+
15+
void init () {
16+
memset(visited, false, sizeof(visited));
17+
memset(trace, 0, sizeof(trace));
18+
for (int i = 0; i < MAX_N; i++) {
19+
edges[i].clear();
20+
}
21+
}
22+
23+
vector<int> dijkstra(int start, int nodes) {
24+
//dijkstra 알고리즘을 위한 거리 배열 - 시작점은 0, 그 외 무한으로 거리 초기화
25+
vector<int> distance(nodes, INF);
26+
distance[start] = 0;
27+
28+
priority_queue<pair<int, int>> pq; //-cost, node 번호
29+
pq.push({0, start});
30+
31+
while (!pq.empty()) {
32+
int cost = -pq.top().first;
33+
int currentNode = pq.top().second;
34+
pq.pop();
35+
36+
if (distance[currentNode] < cost) continue;
37+
38+
for (int i = 0; i < edges[currentNode].size(); i++) {
39+
int nextNode = edges[currentNode][i].first;
40+
int nextCost = cost + edges[currentNode][i].second;
41+
42+
//삭제된 edge 무시
43+
if (edges[currentNode][i].second == -1) continue;
44+
45+
if (distance[nextNode] > nextCost) {
46+
distance[nextNode] = nextCost;
47+
pq.push(make_pair(-nextCost, nextNode));
48+
49+
//trace 갱신
50+
trace[nextNode].clear();
51+
trace[nextNode].push_back(make_pair(currentNode, nextCost));
52+
}
53+
54+
//최단 거리 찾을 때마다 trace update
55+
else if (distance[nextNode] == nextCost)
56+
trace[nextNode].push_back(make_pair(currentNode, nextCost));
57+
}
58+
}
59+
return distance;
60+
}
61+
62+
void BFS(int destination) {
63+
//queue를 이용하여 trace에 해당하는 정점들을 모두 지울 준비를 한다
64+
queue<int> q;
65+
bool visitedNode[MAX_N];
66+
for (int i = 0; i < n; i++) visitedNode[i] = false;
67+
q.push(destination);
68+
visitedNode[destination] = true;
69+
70+
while (!q.empty()) {
71+
int currentNode = q.front();
72+
q.pop();
73+
74+
for (int i = 0; i < trace[currentNode].size(); i++) {
75+
int nextNode = trace[currentNode][i].first;
76+
if (visited[currentNode][nextNode]) continue;
77+
78+
//역순으로 접근하므로 nextNode 기준으로 접근
79+
for (int i = 0; i < edges[nextNode].size(); i++) {
80+
if (edges[nextNode][i].first == currentNode)
81+
edges[nextNode][i].second = -1;
82+
}
83+
if (!visitedNode[nextNode]) {
84+
q.push(nextNode);
85+
visitedNode[nextNode] = true;
86+
}
87+
}
88+
}
89+
}
90+
91+
int main() {
92+
ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
93+
94+
while (1) {
95+
init();
96+
97+
cin >> n >> m;
98+
if (n == 0 && m == 0) break;
99+
100+
int start, goal;
101+
cin >> start >> goal;
102+
103+
for (int i = 0; i < m; i++) {
104+
int from, to, cost;
105+
cin >> from >> to >> cost;
106+
edges[from].push_back({to, cost});
107+
}
108+
109+
dijkstra(start, n);
110+
BFS(goal);
111+
vector<int> result = dijkstra(start, n);
112+
113+
if (result[goal] == INF) cout << -1 << '\n';
114+
else cout << result[goal] << '\n';
115+
}
116+
return 0;
117+
}

0 commit comments

Comments
 (0)