πŸ“– [λ°±μ€€μ•Œκ³ λ¦¬μ¦˜ 풀이] Q.9370 미확인 도착지 문제 풀이 - java

πŸ“– 문제

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

(취읡)B100 μš”μ›, μš”λž€ν•œ μ˜·μ°¨λ¦Όμ„ ν•œ μ„œμ»€μŠ€ μ˜ˆμˆ κ°€ ν•œ 쌍이 ν•œ λ„μ‹œμ˜ 거리듀을 μ΄λ™ν•˜κ³  μžˆλ‹€. λ„ˆμ˜ μž„λ¬΄λŠ” 그듀이 μ–΄λ””λ‘œ κ°€κ³  μžˆλŠ”μ§€ μ•Œμ•„λ‚΄λŠ” 것이닀.

μš°λ¦¬κ°€ μ•Œμ•„λ‚Έ 것은 그듀이 sμ§€μ μ—μ„œ μΆœλ°œν–ˆλ‹€λŠ” 것, 그리고 λͺ©μ μ§€ 후보듀 쀑 ν•˜λ‚˜κ°€ κ·Έλ“€μ˜ λͺ©μ μ§€λΌλŠ” 것이닀. 그듀이 κΈ‰ν•œ 상황이기 λ•Œλ¬Έμ— λͺ©μ μ§€κΉŒμ§€ μš°νšŒν•˜μ§€ μ•Šκ³  μ΅œλ‹¨κ±°λ¦¬λ‘œ 갈 것이라 ν™•μ‹ ν•œλ‹€. 이상이닀. (취읡)

μ–΄νœ΄! (μš”λž€ν•œ μ˜·μ°¨λ¦Όμ„ ν–ˆμ„μ§€λ„ λͺ¨λ₯Ό) λ“€μ˜€κ°€ 어디에도 보이지 μ•ŠλŠ”λ‹€. λ‹€ν–‰νžˆλ„ 당신은 후각이 개만큼 λ›°μ–΄λ‚˜λ‹€. 이 ν›„κ°μœΌλ‘œ 그듀이 g와 h ꡐ차둜 사이에 μžˆλŠ” λ„λ‘œλ₯Ό μ§€λ‚˜κ°”λ‹€λŠ” 것을 μ•Œμ•„λƒˆλ‹€.

이 λ“€μ˜€λŠ” λŒ€μ²΄ μ–΄λ””λ‘œ κ°€κ³  μžˆλŠ” κ²ƒμΌκΉŒ?

example

예제 μž…λ ₯의 두 번째 μΌ€μ΄μŠ€λ₯Ό μ‹œκ°ν™”ν•œ 것이닀. 이 λ“€μ˜€λŠ” νšŒμƒ‰ μ›μ—μ„œ 두 검은 원 쀑 ν•˜λ‚˜λ‘œ κ°€κ³  있고 μ μ„ μœΌλ‘œ ν‘œμ‹œλœ λ„λ‘œμ—μ„œ λƒ„μƒˆλ₯Ό λ§‘μ•˜λ‹€. λ”°λΌμ„œ 그듀은 6으둜 ν–₯ν•˜κ³  μžˆλ‹€.

πŸ” 접근법

BOJ Q.9370 미확인 도착지 λ¬Έμ œμž…λ‹ˆλ‹€.

μš”λž€ν•œ μ˜·μ°¨λ¦Όμ„ ν•œ μ„œμ»€μŠ€ μ˜ˆμˆ κ°€ ν•œ 쌍이 ν•œ λ„μ‹œμ˜ 거리듀을 μ΄λ™ν•˜κ³  μžˆμ„ λ•Œ κ·Έ λ“€μ˜€κ°€ μ–΄λ””λ‘œ κ°€κ³  μžˆλŠ” 것인지 λͺ©μ μ§€λ₯Ό μ°Ύμ•„μ•Ό ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

좜발 μ§€μ μœΌλ‘œ sκ°€ 주어지고 λͺ©μ μ§€ 후보듀이 μ£Όμ–΄μ§‘λ‹ˆλ‹€.

s -> λͺ©μ μ§€ 후보듀 을 μ‚΄νŽ΄λ³΄λ©΄ λ˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

ν•œ μ§€μ μ—μ„œ λͺ©μ μ§€κΉŒμ§€μ˜ μ΅œλ‹¨ 거리λ₯Ό κ΅¬ν•΄μ•Όν•˜λ‹ˆ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•΄ 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

단, 쑰건이 μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ œμ— 주어진 것 처럼 g와 h μ‚¬μ΄μ˜ λ„λ‘œλ₯Ό λ°˜λ“œμ‹œ μ§€λ‚˜κ°€μ•Ό ν•©λ‹ˆλ‹€.

g와 hλ₯Ό λ°˜λ“œμ‹œ μ§€λ‚˜κ°€λŠ” κ²½λ‘œλ“€μ„ λ§Œλ“€μ–΄μ£Όλ©΄ 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

즉,

  1. s -> g -> h -> λͺ©μ μ§€
  2. s -> h -> g -> λͺ©μ μ§€

이 두 경둜 쀑 μ΅œλ‹¨ 거리인 것을 κ΅¬ν•˜λ©΄ λ©λ‹ˆλ‹€.

    int min = Math.min(dijkstra(s, g) + dijkstra(g, h) + dijkstra(h, destination), dijkstra(s, h) + dijkstra(h, g) + dijkstra(g, destination));

λ˜ν•œ! λͺ©μ μ§€ 후보듀 쀑 λΆˆκ°€λŠ₯ν•œ κ²½μš°λ“€μ€ μ œμ™Έν•΄μ•Όν•©λ‹ˆλ‹€.

문제λ₯Ό 잘 μ‚΄νŽ΄λ΄μ•Όν–ˆμŠ΅λ‹ˆλ‹€.

듀이 κΈ‰ν•œ 상황이기 λ•Œλ¬Έμ— λͺ©μ μ§€κΉŒμ§€ μš°νšŒν•˜μ§€ μ•Šκ³  μ΅œλ‹¨κ±°λ¦¬λ‘œ 갈 것이라 ν™•μ‹ ν•œλ‹€. 이상이닀. (취읡)

μœ„μ˜ λ‚΄μš©κ³Ό 같이 이 λ“€μ˜€λŠ” μ ˆλŒ€ λͺ©μ μ§€κΉŒμ§€ μš°νšŒν•˜μ§€ μ•Šκ³  μ΅œλ‹¨κ±°λ¦¬λ‘œ μ›€μ§μΈλ‹€λŠ” 것 μž…λ‹ˆλ‹€.

λͺ©μ μ§€ 후보듀 쀑 λΆˆκ°€λŠ₯ν•œ κ²½μš°λŠ” μš°νšŒν•˜λŠ” κ²½μš°μž…λ‹ˆλ‹€.

κ·ΈλŸ¬λ―€λ‘œ μ΅œμ’…μ μœΌλ‘œ g,h μ‚¬μ΄μ˜ λ„λ‘œλ₯Ό λ°˜λ“œμ‹œ μ§€λ‚˜κ°€λŠ” κ²½λ‘œμ΄λ©΄μ„œ

s->λͺ©μ μ§€κΉŒμ§€μ˜ μ΅œλ‹¨κ²½λ‘œμΈμ§€λ₯Ό ν™•μΈν•˜λ©΄ 닡을 ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

int min = Math.min(dijkstra(s, g) + dijkstra(g, h) + dijkstra(h, destination), dijkstra(s, h) + dijkstra(h, g) + dijkstra(g, destination));
int shortestPath = dijkstra(s, destination);
if (shortestPath == min) {
    answerQueue.add(destination); 
}

πŸ’» μ½”λ“œ


package problem.shortest.Q9370;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;

public class Main_9370 {

    static class Node implements Comparable<Node> {
        int index;
        int distance;

        public Node(int index, int distance) {
            this.index = index;
            this.distance = distance;
        }

        @Override
        public int compareTo(Node target) {
            // μž‘μ€ 거리 λΉ„μš©μ΄ λ¨Όμ € μ˜€λ„λ‘
            return this.distance - target.distance;
        }
    }

    static final int INF = 100000000;
    static int start, end;
    static int T, n, m, t;
    static int s, g, h;
    static List<List<Node>> adList;
    static int[] distance;
    static boolean[] visited;
    static PriorityQueue<Node> priorityQueue;
    static StringBuilder sb = new StringBuilder();


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        T = Integer.parseInt(br.readLine());

        for (int tc = 0; tc < T; tc++) {


            String input[] = br.readLine().split(" ");
            n = Integer.parseInt(input[0]);
            m = Integer.parseInt(input[1]);
            t = Integer.parseInt(input[2]);

            input = br.readLine().split(" ");
            s = Integer.parseInt(input[0]);
            g = Integer.parseInt(input[1]);
            h = Integer.parseInt(input[2]);

            adList = new ArrayList<>();
            // 인덱슀λ₯Ό 1λΆ€ν„° ν•˜κΈ° μœ„ν•΄μ„œ ν•œ 개λ₯Ό λ„£μ–΄λ‘ 
            adList.add(new <Node>ArrayList());
            for (int i = 1; i <= n; i++) {
                adList.add(new <Node>ArrayList());
            }

            for (int i = 0; i < m; i++) {
                String[] temp = br.readLine().split(" ");
                int u = Integer.parseInt(temp[0]);
                int v = Integer.parseInt(temp[1]);
                int cost = Integer.parseInt(temp[2]);
                adList.get(u).add(new Node(v, cost));
                adList.get(v).add(new Node(u, cost));
            }


            PriorityQueue<Integer> answerQueue = new PriorityQueue<>();
            for (int i = 0; i < t; i++) {
                int destination = Integer.parseInt(br.readLine());

                int min = Math.min(dijkstra(s, g) + dijkstra(g, h) + dijkstra(h, destination), dijkstra(s, h) + dijkstra(h, g) + dijkstra(g, destination));
                int shortestPath = dijkstra(s, destination);
                if (shortestPath == min) {
                    answerQueue.add(destination);
                }
            }
            
            while (!answerQueue.isEmpty()) {
                sb.append(answerQueue.poll() + " ");
            }
            sb.append("\n");
        }
        System.out.println(sb.toString());
    }

    private static int dijkstra(int start, int end) {
        priorityQueue = new PriorityQueue<>();
        visited = new boolean[n + 1];
        distance = new int[n + 1];
        Arrays.fill(distance, INF);

        distance[start] = 0;
        priorityQueue.add(new Node(start, 0));

        while (!priorityQueue.isEmpty()) {
            Node current = priorityQueue.poll();

            if (visited[current.index]) {
                continue;
            }
            visited[current.index] = true;
            // μ—°κ²°λœ 정점듀을 확인
            for (Node destination : adList.get(current.index)) {
                //λͺ©μ μ§€ 직행 , ν˜„μž¬κΉŒμ§€ 거리 + ν˜„μž¬μ—μ„œ λͺ©μ μ§€ 거리
                if (distance[destination.index] > distance[current.index] + destination.distance) {
                    // μ΅œμ†Œ 거리 λΉ„μš© κ°±μ‹ 
                    distance[destination.index] = distance[current.index] + destination.distance;
                    priorityQueue.add(new Node(destination.index, distance[destination.index]));
                }
            }
        }
        return distance[end];
    }
}


Written on April 22, 2021