최소경로
2022. 7. 19. 20:50ㆍ알고리즘
오랜만에 알고리즘을 잡으니 최소경로와 최소신장이 헷갈리고 기억도 잘 안나서 정리를 해본다.
# 용어
최소경로
- 가중치가 없다
- bfs
- 가장 먼저 도착하는게 최단
- 도착하자마자 끝내면 된다
- bfs
- 가중치가 있다(완탐)
- 하나의 시작 정점에서 끝 정점까지의 최단 경로
- 다익스트라(dijkstra)
- 음의 가중치 허용x
- 벨만 포드(Bellman-Ford)
- 음의 가중치 허용
- 다익스트라(dijkstra)
- 모든 정점들에 대한 최단 경로
- 플로이드-워샬(Floyd-Warshall)
- 따지고보면 다익스트라를 N만큼 반복해줘도 된다
- 실제로 시간복잡도도비슷하게 나옴
- 플로이드-워샬(Floyd-Warshall)
- 하나의 시작 정점에서 끝 정점까지의 최단 경로
다익스트라Dijkstra
방식
- 그리디하게 진행된다.
- 시작점으로부터 가장 저비용인 곳을 선택하면서 최단 경로를 알아낸다.
- 그리디하게 해결 가능한 이유
- 음의 가중치가 없는 경우에 한하기 때문
- 음의 가중치가 없는 경우에 한하기 때문
배열 사용
map을 사용
boolean[] visited; // 방문배열
int[] distance; //거리배열
// 초기화
Arrays.fill(distance, Integer.MAX_VALUE);
distance[start] = 0;
for(N회반복) {
min = Integer.MAX_VALUE;
for(j=0~N){
// 첫 반복에서 방문x+min보다 적은 비용은 distance[start]가 유일하다.
if(!visited[j] && min > distance[j]) {
min = distance[j];
now = j;
}
}
visited[now] = true;
// 기존비용vs경유비용
for(j=0~N) {
if(!visited[j]
&& map[now][j]!=Integer.MAX_VALUE
&& distance[j] > min+map[now][j]) {
distance[j] = min+map[now][j]
}
}
}
PriorityQueue 사용
graph
를 사용
시작위치로 부터 모든 지점까지의 최단거리를 구하고 distance[end]
를 출력
static class Node implements Comparable<Node> {
int end, cost;
...
}
...
// 도시간 비용을 그래프로 나타냄
ArrayList<ArrayList<Node>> graph = new ArrayList<ArrayList<Node>>();
for (int i = 0; i < N; i++) { // 초기화
graph.add(new ArrayList<Node>());
}
for (int i = 0; i < N; i++) { // 입력받으면서 비용기록
...
graph.get(start).add(new Node(end, cost));
}
// 초기화
Arrays.fill(distance, Integer.MAX_VALUE);
distance[start] = 0;
// pq
PriorityQueue<Node> q = new PriorityQueue();
q.offer(new Node(start, 0));
// 최단거리 탐색
while(!q.isEmpty()){
Node now = q.poll();
// 시작점에서 현재도시로의 비용보다 > 시작점에서 다음 도시로의 비용이 적으면 continue
if(distance[now.end] < now.cost) continue;
// 선택된 노드(pq니까 최저비용 노드)의 인접 노드 확인
for (int i = 0; i < graph.get(now.end).size(); i++) {
Node next = graph.get(now.end).get(i);
// 기존비용vs경유비용
if(distance[next.end] > now.cost+next.cost) {
distance[next.end] = now.cost+next.cost;
q.offer(new Node(next.end, distance[next.end]));
}
}
}
문제
- 백준 1916 최소비용 구하기 https://www.acmicpc.net/problem/1916
'알고리즘' 카테고리의 다른 글
[백준] 21610 마법사 상어와 비바라기(Java) (0) | 2022.08.30 |
---|---|
[BOJ] 24392 영재의 징검다리 (0) | 2022.02.25 |
[백준] [의문]14501번- 퇴사 (0) | 2021.08.15 |