백준 1504번

2025. 2. 14. 08:32·코딩 테스트

문제

https://www.acmicpc.net/problem/1504

알고리즘

1. 최단경로

2. 다익스트라

풀이

경로를 여러 구간으로 나누어 각각의 최단 경로를 구한 후 합산하는 해야합니다.

1. 필수 정점을 포함한 경로 분할

  • 1번 정점에서 시작해서 N번 정점으로 가야 하는데, 그 사이에 반드시 두 개의 정점(v1​와 v2​)을 지나야 합니다.
  • 따라서 전체 경로를 두 개의 경우로 나눌 수 있습니다.
    • 경우 1: 1→v1→v2→N1
    • 경우 2: 1→v2→v1→N1

2. 각 구간별 최단 거리 계산

  • 다익스트라 알고리즘과 같은 최단 경로 알고리즘을 사용하여,
    • 1번 정점에서 모든 정점까지의 최단 경로,
    • v1​에서 모든 정점까지의 최단 경로,
    • v2​에서 모든 정점까지의 최단 경로
      를 각각 구합니다.

3. 경로의 합산과 비교

각 경우에 대해 경로 길이를 구합니다.

  • 경우 1 거리=(1→v1)+(v1→v2)+(v2→N) 
  • 경우 2 거리=(1→v2)+(v2→v1)+(v1→N)
  • 이 두 값 중 더 짧은 경로를 최종 답으로 선택합니다.

코드

public class Main {

	public static void main(String[] args) {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			List<Integer> NE = Arrays.stream(br.readLine().split(" "))
				.map(Integer::parseInt)
				.collect(Collectors.toList());
			ArrayList<List<int[]>> graph = new ArrayList<>();
			for (int i = 0; i < NE.get(0); i++) {
				graph.add(new ArrayList<>());
			}

			for (int i = 0; i < NE.get(1); i++) {
				String[] s = br.readLine().split(" ");
				int u = Integer.parseInt(s[0]) - 1;
				int v = Integer.parseInt(s[1]) - 1;
				int w = Integer.parseInt(s[2]);
				graph.get(u).add(new int[] {v, w});
				graph.get(v).add(new int[] {u, w});
			}
			List<Integer> sortedList1 = Arrays.stream(br.readLine().split(" "))
				.map(Integer::parseInt)
				.map(integer -> integer - 1)
				.collect(Collectors.toList());

			List<Integer> des1 = new ArrayList<>(List.of(0, sortedList1.get(0), sortedList1.get(1), NE.get(0) - 1));
			List<Integer> des2 = new ArrayList<>(List.of(0, sortedList1.get(1), sortedList1.get(0), NE.get(0) - 1));

			long min = 0;
			long min2 = 0;
			min = bfs(des1, min, graph);
			min2 = bfs(des2, min2, graph);
			long min1 = Math.min(min2, min);
			if (min1 >= Long.MAX_VALUE / 2) {
				System.out.println(-1);
			} else {
				System.out.println(min1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static long bfs(List<Integer> des, long min, ArrayList<List<int[]>> graph) {
		for (int i = 0; i < des.size() - 1; i++) {
			PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparing(ints -> ints[1]));
			pq.add(new int[] {des.get(i), 0});
			long[] dist = new long[graph.size()];
			Arrays.fill(dist, Long.MAX_VALUE / 2);
			dist[des.get(i)] = 0;

			while (!pq.isEmpty()) {
				int[] poll = pq.poll();
				for (int[] ints : graph.get(poll[0])) {
					if (dist[ints[0]] <= poll[1] + ints[1]) {
						continue;
					}
					dist[ints[0]] = poll[1] + ints[1];
					pq.add(new int[] {ints[0], poll[1] + ints[1]});
				}
			}
			if (dist[des.get(i + 1)] >= Long.MAX_VALUE / 2) {
				return Long.MAX_VALUE / 2;
			}
			min += dist[des.get(i + 1)];
		}
		return min;
	}
}

'코딩 테스트' 카테고리의 다른 글

백준 13549  (0) 2025.02.20
백준 1707  (0) 2025.02.17
백준 1197번  (0) 2025.02.10
백준 11404번  (0) 2025.02.03
백준 11403번  (1) 2025.02.01
'코딩 테스트' 카테고리의 다른 글
  • 백준 13549
  • 백준 1707
  • 백준 1197번
  • 백준 11404번
jamin
jamin
  • jamin
    jamin
    jamin
  • 전체
    오늘
    어제
    • 전체 (82)
      • 트러블슈팅 (31)
        • 회사 (25)
        • 개인 (6)
      • 개념 저장소 (19)
        • coroutine (10)
        • spring reactive (9)
        • network (0)
      • 코딩 테스트 (31)
  • 태그

    JPA
    reactive
    그리디 알고리즘
    dfs
    Kotlin
    대용량 데이터
    spring boot
    cluster mode
    BFS
    다이나믹 프로그래밍
    정렬
    분리집합
    instancio
    coroutine
    백준 23758
    DP
    error alram
    mirroring mode
    백준
    코딩테스트
    코테
    spring reactive
    sinks
    수학
    log
    누적합
    batch
    경로압축
    그리디
    다익스트라
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jamin
백준 1504번
상단으로

티스토리툴바