다익스트라
그래프에서 한 정점에서 다른 모든 정점 까지의 최단 거리를 구할 수 있는 알고리즘이다.
시간복잡도는 ElogE or ElogV
자료구조
다익스트라 알고리즘에서 저장해야하는 정보는 다음과 같다.
- 노드별 최소 비용을 저장할 배열
- 간선의 노드 연결과 비용을 저장할 vector 배열
- 경로 탐색을 위해 prev 배열
여기서 adj에는 adj[시작노드] = {비용, 끝노드} 형태로 정보를 저장한다.
비용이 key인 이유는 비용을 기준으로 priority_queue에 넣기 위해서...!
int d[1005];
vector<pair<int, int>> adj[1005];
int pre[1005];
이때 최소 비용 배열 d는 INF 값으로 초기화 해줘야한다.
int INF = 0x3f3f3f3f;
fill(d, d+n+1, INF);
구현
다익스트라 알고리즘은 시작정점에서 부터 하나씩 최소 비용이 드는 노드를 선택해가면서 전체 최소비용을 구한다.
특정 노드까지 가는 비용과 노드를 저장할 수 있는 우선순위 큐를 선언한 다음
시작노드까지의 거리는 0, pq에 push한다.
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> pq;
d[st] = 0;
pq.push({d[st], st});
이 후 pq가 빌때까지 노드를 선택하고 최소비용 배열을 업데이트 하면 된다.
최소비용 트리의 값과 pq의 비용이 다르다면 이미 더 작은 비용으로 경로가 연결된 것이므로 continue 처리를 한다.
update 후보군들을 cur 노드와 연결된 노드들이므로 adj에서 가져온다.
이때 d의 nxt까지의 비용과 cur까지의 비용 + cur에서 nxt의 비용을 비교해 더 갱신이 필요하면 해준다.
갱신시 d를 업데이트하고 pq에 nxt까지의 비용과 nxt를 push 해준다.
이때 경로복원을 위한 pre도 수정한다.
while(!pq.empty())
{
auto cur = pq.top(); pq.pop();
if(d[cur.Y] != cur.X) continue;
for(auto nxt: adj[cur.Y]){
if(d[nxt.Y] <= d[cur.Y] + nxt.X) continue;
d[nxt.Y] = d[cur.Y] + nxt.X;
pq.push({d[nxt.Y], nxt.Y});
pre[nxt.Y] = cur.Y;
경로 복원
경로 복원의 경우 prev[end]에서 부터 값이 start 노드가 나올때까지 타고 들어가면 된다.
vector<int> path;
cur = end;
while(cur != start){
path.push_back(cur);
cur = pre[cur];
}
path.push_back(cur);
reverse(path.begin(), path.end());
for(int node: path) cout << node << ' ';
'Algorithm' 카테고리의 다른 글
[Algorithm] 백준 15683 - 감시 (0) | 2025.04.29 |
---|---|
[Algorithm] 트리에서 BFS, DFS (0) | 2025.04.02 |
[Algorithm] 이진수로 변경 & 산모양 출력 (0) | 2025.03.15 |
[Algorithm] 백준 2579 - 계단 오르기 (0) | 2025.03.14 |
[Algorithm] 옥상 정원 꾸미기 (백준 6198) (0) | 2024.12.29 |