BOJ 27180 Тяжелый груз
BOJ 27180 Тяжелый груз
문제 내용
당신은 어떤 창고에서 특별한 리프트를 이용해서 거대한 상자를 옮기려고 합니다. 이 창고는 개의 방과 개의 복도로 이루어져 있으며, 각 방에는 1부터 까지의 서로 다른 번호가 붙어 있습니다. 각각의 복도는 서로 다른 두 방을 연결하며, 모든 복도를 통해서 양방향으로 이동할 수 있습니다.
거대한 상자는 처음에 1번 방에 있으며, 리프트 위에 올려져 있습니다. 당신은 상자를 옮기기 위해 다음과 같은 행동을 할 수 있습니다.
- 번 방에서 리프트 위에 상자가 올려져 있을 때, 번 방에서 하나의 복도로 연결된 번 방에 상자를 내려놓을 수 있습니다. 리프트는 번 방에 그대로 있습니다. 이 행동의 비용은 1입니다.
- 번 방에 상자가 놓여 있고 번 방에서 하나의 복도로 연결된 번 방에 리프트가 있을 때, 상자를 들어올릴 수 있습니다. 리프트와 상자는 번 방에 있게 됩니다. 이 행동의 비용은 1입니다.
- 번 방에 상자가 놓여 있고 ()번 방에 리프트가 있을 때, 번 방에서 하나의 복도로 연결된 번 방으로 리프트를 이동할 수 있습니다. 번 방에 상자가 있다면 이동할 수 없습니다. 이 행동의 비용은 0입니다.
1번 방을 제외한 번 방에 리프트 위에 상자가 올려져 있도록 하기 위해 필요한 최소 비용을 구하세요.
입력
첫 번째 줄에는 테스트 케이스의 개수 가 주어집니다. ()
각 테스트 케이스에 대해, 첫 번째 줄에 과 이 주어집니다. (, )
다음 줄에 걸쳐서 번째 줄에는 번째 복도가 잇는 두 방의 번호 와 가 주어집니다. (, )
주어지는 그래프는 단순 연결 그래프이며, 와 의 총합은 각각 을 초과하지 않습니다.
출력
각 테스트 케이스에 대해, 번 방으로 상자와 리프트를 옮기는 데 필요한 최소 비용을 순서대로 한 줄에 출력합니다. 번 방에 대해, 어떻게 옮겨도 번 방으로 옮길 수 없다면 -1을 대신 출력합니다.
문제 풀이
스포일러
주어진 그래프에서 BCC들을 계산합니다. 그러면 다음과 같은 관찰을 할 수 있습니다.
- 상자가 번 방에 있을 때 번 방이 단절점이면, 리프트는 번 방에 이웃한 방들 중 다른 BCC에 속한 방으로 이동할 수 없습니다.
- 따라서, 상자와 리프트를 다른 BCC로 이동하는 유일한 방법은 리프트와 상자가 동시에 단절점에 오도록 하는 것입니다.
- 하나의 BCC 내에서는 상자가 어디에 있든 리프트를 항상 원하는 곳으로 옮길 수 있습니다.
이를 이용하여, 다음과 같이 BCC별로 BFS를 돌리는 방법을 생각할 수 있습니다.
- 현재의 상태를 (상자의 위치, 상자가 리프트 위에 있는지 여부)로 나타냅니다.
- 현재의 BCC 내에서 BFS를 돌립니다. 이때 상자가 이웃한 방으로 이동할 때마다 거리가 1 증가하고, 상자가 리프트 위에 있는지 여부가 바뀝니다.
- 현재의 BCC에 속한 점들 중 단절점 에 대해, (, true)가 도달 가능하다면, 를 포함하는 다른 BCC들에 대해 탐색을 반복합니다.
- 이때 새로운 BCC에서의 초기 조건은 (, true)의 거리를 그대로 두고, (, false)의 거리를 무한으로 다시 바꿔야 합니다. 이전 BCC에서의 (, false)와 현재 BCC에서의 (, false)는 호환되지 않기 때문입니다.
이를 총 시간 복잡도 이 되도록 잘 구현하면 됩니다.
Last updated on