[백준]#15971 두 로봇

SeungBird·2021년 4월 21일
0

⌨알고리즘(백준)

목록 보기
315/401

문제

2018년 강원도에서 새로운 동굴이 발견되었다. 이 동굴에는 총 N개의 넓은 방이 존재하며 좁은 통로로 서로 연결되어 있는 것으로 밝혀졌다. N개의 방은 1번부터 N번까지의 번호를 붙여 1번 방, 2번 방, …, N번 방으로 부른다. 통로는 정확히 N-1개가 발견되었는데, 각각 서로 다른 두 방 사이를 연결시켜 주며 중간에 다른 통로와 이어지는 경우는 없다고 한다. 또한 이 통로들을 이용하여 임의의 두 방 사이를 이동하는 것이 가능하며, 임의의 두 방 사이를 이동할 때 같은 통로를 두 번 이상 지나지 않는 경로는 유일한 것으로 밝혀졌다.

새로 발견된 동굴을 조사하기 위해 동굴 탐사 로봇 두 대를 이용하기로 하였다. 두 로봇은 어떤 시점이 되면 각자가 획득한 정보를 공유하기 위해 통신을 해야 한다. 두 로봇이 서로 통신을 하기 위해서는 동굴 내의 같은 통로 위에 위치해야만 한다. 참고로 임의의 통로의 양 끝에 위치한 두 방들도 그 통로 위에 위치해 있다고 간주한다.

<그림 1> 동굴 내부를 간략히 표현한 그림

<그림 1>은 방이 9개인 동굴 내부를 간략하게 나타낸 예이다. <그림 1>에서 방은 원으로 표현되어 있으며 원 안의 수는 방 번호이다. 8개의 통로는 두 원 사이의 선분으로 표시되어 있으며 그 위의 정수 값이 통로의 길이이다. 예를 들어, 5번 방과 9번 방 사이에 길이가 6 인 통로가 있음을 알 수 있다. 만약 두 로봇이 1번 방과 9번 방에 위치해 있다면, 각각 2번 방과 5번 방으로 이동한 후 통신할 수 있으며 이때 이동한 거리의 합은 14로 최소이다.

동굴 내의 통로에 대한 정보와 두 로봇의 현재 위치가 입력으로 주어질 때, 서로 통신하기 위해 이동해야 하는 거리의 합의 최솟값을 계산하는 프로그램을 작성하시오.

동굴의 각 통로는 양 끝에 위치한 두 방의 번호와 그 길이로 주어진다. 두 로봇의 위치는 방 번호로 주어진다.

입력

표준 입력으로 동굴의 방의 개수 N과 두 로봇이 위치한 방의 번호가 세 개의 양의 정수로 공백으로 분리되어 첫 줄에 주어진다. 이후 동굴의 통로 N-1개가 한 줄에 하나씩 주어진다. 각 통로는 세 개의 양의 정수로 공백으로 분리되어 한 줄에 주어지며, 앞 두 정수는 통로의 양 끝에 위치한 방의 번호를, 세 번째 정수는 그 통로의 길이를 의미한다.

출력

표준 출력으로 두 로봇이 서로 통신하기 위해 현재 위치에서 이동해야 하는 거리의 합의 최솟값을 정수로 출력한다.

제한

모든 서브태스크에서 1 ≤ N ≤ 100,000이며, 통로의 길이는 1,000을 넘지 않는다.

예제 입력 1

5 1 5
1 2 1
2 3 2
3 4 3
4 5 4

예제 출력 1

6

예제 입력 2

9 1 9
1 2 8
2 3 6
2 4 5
2 5 10
9 5 6
6 5 14
6 7 7
8 6 7

예제 출력 2

14

풀이

이 문제는 bfs(너비 우선 탐색) 알고리즘과 dijkstra(다익스트라) 알고리즘을 이용해서 풀 수 있었다. bfs를 이용해 다익스트라를 구현하고 로봇간 최단거리에서 가장 큰 cost를 빼서 답을 구했다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static ArrayList<Node>[] tree;
    static int N;

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");
        N = Integer.parseInt(input[0]);
        int robot1 = Integer.parseInt(input[1]);
        int robot2 = Integer.parseInt(input[2]);
        tree = new ArrayList[N+1];
        for(int i=1; i<=N; i++)
            tree[i] = new ArrayList<>();

        for(int i=0; i<N-1; i++) {
            input = br.readLine().split(" ");
            int start = Integer.parseInt(input[0]);
            int end = Integer.parseInt(input[1]);
            int cost = Integer.parseInt(input[2]);

            tree[start].add(new Node(end, cost));
            tree[end].add(new Node(start, cost));
        }

        bfs(robot1, robot2);
    }

    public static void bfs(int robot1, int robot2) {
        Queue<Pair> queue = new LinkedList<>();
        boolean[] visited = new boolean[N+1];
        visited[robot1] = true;
        queue.add(new Pair(robot1, 0, 0));

        while(!queue.isEmpty()) {
            Pair temp = queue.poll();

            if(temp.x==robot2) {
                System.out.println(temp.cost- temp.max);
                break;
            }

            for(Node n : tree[temp.x]) {
                if(!visited[n.end]) {
                    visited[n.end] = true;
                    queue.add(new Pair(n.end, temp.cost+n.cost, Math.max(temp.max, n.cost)));
                }
            }
        }

    }

    public static class Node {
        int end;
        int cost;

        public Node(int end, int cost) {
            this.end = end;
            this.cost = cost;
        }
    }

    public static class Pair {
        int x;
        int cost;
        int max;

        public Pair(int x, int cost, int max) {
            this.x = x;
            this.cost = cost;
            this.max = max;
        }
    }
}
profile
👶🏻Jr. Programmer

0개의 댓글