-
[백준]11657. 타임머신알고리즘/백준 2021. 1. 7. 00:26
📄 링크
💡 문제 분석
음의 가중치를 가질 수 있는 최소 비용 문제입니다.
음의 가중치를 가지고 있는지 판단할 수 있는 벨만-포드 알고리즘을 사용 해야겠다고 생각했습니다.
V - 1번을 완화작업을 하면 모든 정점의 최소 비용을 알 수 있습니다. 그리고 V번째 완화 작업을 했을 때 실패하지 않고 성공한다면 음수 간선이 존재하는 것입니다.문제를 풀면서 계속 출력초과 에러가 발생해서 계속 고민을 하다가 아주 큰 음수 가중치를 계속 더하면 언더플로우가 발생할 수 있다는 것을 깨달았습니다.
그래서 upper 배열 값을 long 타입으로 바꿨더니 해결이 되었습니다.
⌨️ 코드
import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class _11657_타임머신 { static class Edge { int to, weight; public Edge(int to, int weight) { this.to = to; this.weight = weight; } } final static int INF = 1000000000; static long[] upper; static int V, E; static ArrayList<Edge>[] adj; static boolean bellmanFord(int src) { upper = new long[V + 1]; Arrays.fill(upper, INF); upper[src] = 0; for(int iter = 1; iter <= V; ++iter) { boolean chk = false; for(int here = 1; here <= V; ++here) for(int i = 0; i < adj[here].size(); ++i) { int there = adj[here].get(i).to; int cost = adj[here].get(i).weight; if(upper[here] != INF && upper[there] > upper[here] + cost) { upper[there] = upper[here] + cost; chk = true; if(iter == V) return false; } } if(!chk) return true; } return true; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); V = sc.nextInt(); E = sc.nextInt(); adj = new ArrayList[V + 1]; for(int i = 0; i <= V; i++) adj[i] = new ArrayList<Edge>(); for(int i = 0; i < E; i++) { int u = sc.nextInt(), v = sc.nextInt(), w = sc.nextInt(); adj[u].add(new Edge(v, w)); } if(bellmanFord(1)) for(int i = 2; i <= V; i++) System.out.println((upper[i] == INF ? -1 : upper[i])); else System.out.println(-1); sc.close(); } }
📋 회고
- 언더플로우는 한 번도 못봤는데 염두해야 겠음..
- 벨만-포드
'알고리즘 > 백준' 카테고리의 다른 글
[백준]1629. 곱셈 (0) 2021.01.08 [백준]1504. 특정한 최단경로 (0) 2021.01.08 [백준]1238. 파티 (0) 2021.01.07 [백준]1916. 최소비용 구하기 (0) 2021.01.07 [백준]10021. Watering the Fields (0) 2021.01.05