λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm/Baekjoon

[8μ£Όμ°¨] λ°±μ€€ 18352 νŠΉμ • 거리의 λ„μ‹œ μ°ΎκΈ°

νŠΉμ • 거리의 λ„μ‹œ μ°ΎκΈ° λ¬Έμ œν’€μ΄

πŸ’»Q

μ–΄λ–€ λ‚˜λΌμ—λŠ” 1λ²ˆλΆ€ν„° Nλ²ˆκΉŒμ§€μ˜ λ„μ‹œμ™€ M개의 단방ν–₯ λ„λ‘œκ°€ μ‘΄μž¬ν•œλ‹€.
λͺ¨λ“  λ„λ‘œμ˜ κ±°λ¦¬λŠ” 1이닀.

이 λ•Œ νŠΉμ •ν•œ λ„μ‹œ Xλ‘œλΆ€ν„° μΆœλ°œν•˜μ—¬ 도달할 수 μžˆλŠ” λͺ¨λ“  λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 μ •ν™•νžˆ K인 λͺ¨λ“  λ„μ‹œλ“€μ˜ 번호λ₯Ό 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
λ˜ν•œ 좜발 λ„μ‹œ Xμ—μ„œ 좜발 λ„μ‹œ X둜 κ°€λŠ” μ΅œλ‹¨ κ±°λ¦¬λŠ” 항상 0이라고 κ°€μ •ν•œλ‹€.

예λ₯Ό λ“€μ–΄ N=4, K=2, X=1일 λ•Œ λ‹€μŒκ³Ό 같이 κ·Έλž˜ν”„κ°€ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•˜μž.

이 λ•Œ 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ 도달할 수 μžˆλŠ” λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 2인 λ„μ‹œλŠ” 4번 λ„μ‹œ 뿐이닀.  
2번과 3번 λ„μ‹œμ˜ 경우, μ΅œλ‹¨ 거리가 1이기 λ•Œλ¬Έμ— 좜λ ₯ν•˜μ§€ μ•ŠλŠ”λ‹€.
μž…λ ₯

첫째 쀄에 λ„μ‹œμ˜ 개수 N, λ„λ‘œμ˜ 개수 M, 거리 정보 K, 좜발 λ„μ‹œμ˜ 번호 Xκ°€ μ£Όμ–΄μ§„λ‹€.
(2 ≤ N ≤ 300,000, 1 ≤ M ≤ 1,000,000, 1 ≤ K ≤ 300,000, 1 ≤ X ≤ N) λ‘˜μ§Έ 쀄뢀터 M개의 쀄에 κ±Έμ³μ„œ 두 개의 μžμ—°μˆ˜ A, Bκ°€ 곡백을 κΈ°μ€€μœΌλ‘œ κ΅¬λΆ„λ˜μ–΄ μ£Όμ–΄μ§„λ‹€.
μ΄λŠ” A번 λ„μ‹œμ—μ„œ B번 λ„μ‹œλ‘œ μ΄λ™ν•˜λŠ” 단방ν–₯ λ„λ‘œκ°€ μ‘΄μž¬ν•œλ‹€λŠ” μ˜λ―Έλ‹€.
(1 ≤ A, B ≤ N) 단, A와 BλŠ” μ„œλ‘œ λ‹€λ₯Έ μžμ—°μˆ˜μ΄λ‹€.
좜λ ₯

Xλ‘œλΆ€ν„° μΆœλ°œν•˜μ—¬ 도달할 수 μžˆλŠ” λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 K인 λͺ¨λ“  λ„μ‹œμ˜ 번호λ₯Ό ν•œ 쀄에 ν•˜λ‚˜μ”© μ˜€λ¦„μ°¨μˆœμœΌλ‘œ 좜λ ₯ν•œλ‹€.

이 λ•Œ 도달할 수 μžˆλŠ” λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 K인 λ„μ‹œκ°€ ν•˜λ‚˜λ„ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ -1을 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1
예제 좜λ ₯1
예제 μž…λ ₯2
예제 좜λ ₯2
예제 μž…λ ₯3
예제 좜λ ₯3

 

πŸ’‘A

λ‹€μ΅μŠ€νŠΈλΌ 풀이

import java.util.*;

class Main {
    private static int N, M, K, X;
    private static int[] distance;  //μΆœλ°œλ„μ‹œμΈ Xμ™€μ˜ μ΅œλ‹¨κ²½λ‘œ
    private static ArrayList<Edge>[] edgeList;  //λ„μ‹œ μΈμ ‘λ¦¬μŠ€νŠΈ

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        M = sc.nextInt();
        K = sc.nextInt();
        X = sc.nextInt();
        
        //생성 μ΄ˆκΈ°ν™”
        distance = new int[N + 1];
        edgeList = new ArrayList[N + 1];
        Arrays.fill(distance, Integer.MAX_VALUE);
        
        for(int i=1; i<=N; i++) {
            edgeList[i] = new ArrayList<>();
        }
        
        //경둜 μ΄ˆκΈ°ν™”
        for(int i=0; i<M; i++) {
            int start = sc.nextInt();
            int end = sc.nextInt();
            //A번 λ„μ‹œμ—μ„œ B번 λ„μ‹œλ‘œ μ΄λ™ν•˜λŠ” 단방ν–₯ λ„λ‘œκ°€ 쑴재
            edgeList[start].add(new Edge(end, 1));
        }
        //좜발 λ„μ‹œ
        distance[X] = 0;
        dijkstra();
        int answer = 0;
        
        for(int i=1; i<distance.length; i++){
            int d = distance[i];
            
            if(d==K) {
                System.out.println(i);
                answer++;
            }
        }
        if (answer==0) System.out.println(-1);
    }

    private static void dijkstra() {
        PriorityQueue<Edge> queue = new PriorityQueue<>();
        queue.add(new Edge(X, 0));
        
        while(!queue.isEmpty()) {
            Edge edge = queue.poll();
            int vertex = edge.vertex;
            int cost = edge.cost;
            
            if(distance[vertex]<cost) {
                continue;
            }
            
            //ν•΄λ‹Ή λ„μ‹œμ™€ μ—°κ²° λ˜μ–΄ μžˆλŠ” λ„μ‹œλ“€ 탐색
            for(int i=0; i<edgeList[vertex].size(); i++) {  
                int v = edgeList[vertex].get(i).vertex;
                int c = edgeList[vertex].get(i).cost + cost;
                
                //μ΅œλ‹¨ 경둜 μ €μž₯
                if(distance[v]>c) { 
                    distance[v] = c;
                    queue.add(new Edge(v, c));
                }
            }
        }
    }

    private static class Edge implements Comparable<Edge> {
        int vertex;
        int cost;

        public Edge(int vertex, int cost) {
            this.vertex = vertex;
            this.cost = cost;
        }

        @Override
        public int compareTo(Edge o) { 
            return cost - o.cost;
        }
    }
}