천복만복 프로그래밍/천복만복 알고리즘 이론
[알고리즘] 최단거리 알고리즘 SPFA Java 참고코드
U&MeBlue
2022. 4. 29. 20:04
SPFA(Shortest Path Faster Algorithm) 은 벨만포드 알고리즘을 개선한 알고리즘이다. v - 1번 반복하는 동안 매 반복마다 모든 간선에 대해서 간선 경감을 진행하는 대신, 간선 경감이 일어나는 정점에 대해서만 그 정점에 연결된 간선들에 대해서 다음 간선 경감을 진행하는 방식이다. 최악의 경우 O(V^3) 의 시간복잡도를 갖지만, 평균적으로 O(E) 의 시간복잡도를 갖는다.
https://www.acmicpc.net/problem/11657
package 최단경로.spfa.타임머신;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
int n = Integer.parseInt(strs[0]);
int m = Integer.parseInt(strs[1]);
long[] dist = new long[n + 1];
for (int i = 1; i <= n; i++) {
dist[i] = Long.MAX_VALUE;
}
ArrayList<int[]>[] arr = (ArrayList<int[]>[]) new ArrayList[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = new ArrayList<int[]>();
}
for (int i = 0; i < m; i++) {
String[] nums = br.readLine().split(" ");
int a = Integer.parseInt(nums[0]);
int b = Integer.parseInt(nums[1]);
int c = Integer.parseInt(nums[2]);
arr[a].add(new int[] {b, c});
}
boolean[] check = new boolean[n + 1];
int[] cnt = new int[n + 1];
Queue<Integer> q = new LinkedList<>();
check[1] = true;
dist[1] = 0;
cnt[1]++;
q.offer(1);
while(!q.isEmpty()) {
int cur = q.poll();
check[cur] = false;
for (int i = 0; i < arr[cur].size(); i++) {
int next = arr[cur].get(i)[0];
int cost = arr[cur].get(i)[1];
if (dist[next] > dist[cur] + cost) {
dist[next] = dist[cur] + cost;
if (check[next] == false) {
check[next] = true;
q.offer(next);
cnt[next]++;
if (cnt[next] >= n) {
System.out.println(-1);
return;
}
}
}
}
}
for (int i = 2; i <= n; i++) {
if (dist[i] == Long.MAX_VALUE) System.out.println(-1);
else System.out.println(dist[i]);
}
}
}
728x90