πŸ“– [λ°±μ€€μ•Œκ³ λ¦¬μ¦˜ 풀이] Q.1504 νŠΉμ •ν•œ μ΅œλ‹¨ 경둜

πŸ“– 문제

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

λ°©ν–₯성이 μ—†λŠ” κ·Έλž˜ν”„κ°€ 주어진닀. μ„Έμ€€μ΄λŠ” 1번 μ •μ μ—μ„œ N번 μ •μ μœΌλ‘œ μ΅œλ‹¨ 거리둜 μ΄λ™ν•˜λ €κ³  ν•œλ‹€.

λ˜ν•œ μ„Έμ€€μ΄λŠ” 두 가지 쑰건을 λ§Œμ‘±ν•˜λ©΄μ„œ μ΄λ™ν•˜λŠ” νŠΉμ •ν•œ μ΅œλ‹¨ 경둜λ₯Ό κ΅¬ν•˜κ³  싢은데,

그것은 λ°”λ‘œ μž„μ˜λ‘œ 주어진 두 정점은 λ°˜λ“œμ‹œ 톡과해야 ν•œλ‹€λŠ” 것이닀.

μ„Έμ€€μ΄λŠ” ν•œλ²ˆ μ΄λ™ν–ˆλ˜ 정점은 λ¬Όλ‘ , ν•œλ²ˆ μ΄λ™ν–ˆλ˜ 간선도 λ‹€μ‹œ 이동할 수 μžˆλ‹€.

ν•˜μ§€λ§Œ λ°˜λ“œμ‹œ μ΅œλ‹¨ 경둜둜 이동해야 ν•œλ‹€λŠ” 사싀에 μ£Όμ˜ν•˜λΌ. 1번 μ •μ μ—μ„œ N번 μ •μ μœΌλ‘œ 이동할 λ•Œ,

주어진 두 정점을 λ°˜λ“œμ‹œ κ±°μΉ˜λ©΄μ„œ μ΅œλ‹¨ 경둜둜 μ΄λ™ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

πŸ” 접근법

BOJ Q.1504 νŠΉμ •ν•œ μ΅œλ‹¨ 경둜 λ¬Έμ œμž…λ‹ˆλ‹€.

κΈ°λ³Έ 바탕은 λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ λ‹€μ†Œ λ‹€λ₯Έ 것은 μž„μ˜λ‘œ 주어진 두 정점을 λ°˜λ“œμ‹œ 톡과해야 ν•œλ‹€λŠ” 것 μž…λ‹ˆλ‹€.

λ„μ°©μ§€κΉŒμ§€ 정점 1 , 정점 2 λ₯Ό λ°˜λ“œμ‹œ ν†΅κ³Όν•˜λŠ” κ²½μš°λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ‹œμž‘ -> 정점1 -> 정점2 -> 끝 μ‹œμž‘ -> 정점2 -> 정점1 -> 끝

μ΄λ ‡κ²Œ 두가지 κ²½μš°μ€‘μ— 더 μ΅œλ‹¨ 경둜λ₯Ό 찾으면 풀이가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

solve ν•¨μˆ˜ => λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•΄ 주어진 μ‹œμž‘μ λΆ€ν„° λκΉŒμ§€μ˜ μ΅œλ‹¨κ²½λ‘œλ₯Ό κ΅¬ν•˜λŠ” ν•¨μˆ˜ solve ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ μ•„λž˜μ™€ 같이 μ‹œμž‘ -> 정점1 -> 정점2 -> 끝 μ‹œμž‘ -> 정점2 -> 정점1 -> 끝

두가지 쀑 더 짧은 κ²½λ‘œκ°€ νŠΉμ •ν•œ μ΅œλ‹¨ κ²½λ‘œμž…λ‹ˆλ‹€.

             answer[0] += solve(1,first)+solve(first,second)+solve(second,N);
             answer[1] += solve(1,second)+solve(second,first)+solve(first,N);

πŸ’» μ½”λ“œ

package problem.shortest.Q1504;

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_1504 {

    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 N, M, start,end;
    static List<List<Node>> adList;
    static int[] distance;
    static boolean[] visited;
    static PriorityQueue<Node> priorityQueue;


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

        String input[] = br.readLine().split(" ");

        N = Integer.parseInt(input[0]);
        M = Integer.parseInt(input[1]);

        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));
        }

        input = br.readLine().split(" ");
        int first = Integer.parseInt(input[0]);
        int second = Integer.parseInt(input[1]);

        answer[0] += solve(1,first)+solve(first,second)+solve(second,N);
        answer[1] += solve(1,second)+solve(second,first)+solve(first,N);

        int shortestPathCost = Integer.min(answer[0],answer[1]);
        if(shortestPathCost>=INF)
            System.out.println(-1);
        else
            System.out.println(shortestPathCost);
    }

    private static int solve(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 October 24, 2020