문제집 추천, 이 문제집에 나온 유형들만 공부해도 코딩테스트는 거뜬: https://www.acmicpc.net/workbook/by/BaaaaaaaaaaarkingDog
5214번: 환승 문제 보러 가기
제한시간: 2초
메모리 제한: 256 MB
문제
아주 먼 미래에 사람들이 가장 많이 사용하는 대중교통은 하이퍼튜브이다. 하이퍼튜브 하나는 역 K개를 서로 연결한다. 1번역에서 N번역으로 가는데 방문하는 최소 역의 수는 몇 개일까?
입력
첫째 줄에 역의 수 N과 한 하이퍼튜브가 서로 연결하는 역의 개수 K, 하이퍼튜브의 개수 M이 주어진다. (1 ≤ N ≤ 100,000, 1 ≤ K, M ≤ 1000)
다음 M개 줄에는 하이퍼튜브의 정보가 한 줄에 하나씩 주어진다. 총 K개 숫자가 주어지며, 이 숫자는 그 하이퍼튜브가 서로 연결하는 역의 번호이다.
출력
첫째 줄에 1번역에서 N번역으로 가는데 방문하는 역의 개수의 최솟값을 출력한다. 만약, 갈 수 없다면 -1을 출력한다.
예제 입력 1
9 3 5
1 2 3
1 4 5
3 6 7
5 6 7
6 8 9
예제 출력 1
4
역시나 문제를 이해하기도 풀이를 봐도 이해하기 어려운 문제였다.
[1] 하이퍼에서 (1)역에서 (3)역까지
[3] 하이퍼에서 (3)역에서 (6)역까지
[5] 하이퍼에서 (6)역에서 (9)역까지 가면 된다. 이러면 1-3-6-9 로 4번만에
또는
[2] 하이퍼에서 (1)역에서 (5)역까지
[4] 하이퍼에서 (5)역에서 (6)역까지
[5] 하이퍼에서 (6)역부터 (9)역까지 가면 된다. 이러면 1-5-6-9로 4번만에 간다.
dummy station으로 풀라고 하는데 그 풀이를 해석해보자.
하이퍼와 역을 따로 만들지 말고 하나의 그래프에 정보를 넣는다.
graph =[[] for _ in range(1+N+M)]
graph의 N+1번째 즉 10부터 하이퍼의 정보를 넣는다. 즉, [1] 하이퍼 [1,2,3]은 graph[10]=[1,2,3] 이고
[2] 하이퍼 [1,4,5]는 graph[11]=[1,4,5]이다.
graph의 1번째부터 9번째까지 역 1에 대한 하이퍼 정보를 연결한다. 즉 graph[1]에는 1역을 통과하는 하이퍼 index를 넣는다. graph[1]=[10,11]이 된다.
다시 정리하면
1. 경로의 노드를 "역"과 "하이퍼튜브"로 설정한다. 따라서 배열의 사이즈는 N+M+1이다
2. '역-하이퍼-역' 구조로 경로를 저장한다. 경로 배열의 1부터 N까지는 역, N+1부터 N+M까지는 하이퍼튜브
3. BFS로 길을 찾으면서 하이퍼튜브로 가면 이동 횟수에 변화를 주지 않고 역에 도착하면 횟수를 증가시킨다
4. 목적지에 도착하면 이동 횟수 출력
즉 하이퍼 노드로 가서 하이퍼 노드의 역 정보를 살피는데 역을 이동할때는 cnt+1이 되고
하이퍼 노드에서 하이퍼 노드로 이동할 때는 역을 이동하는게 아니라서 cnt+1을 하지 않음
cnt=1
[1] 하이퍼에서 (1)역에서 (3)역까지 --> 1역 노드에서 3역 노드로 cnt+=1을 한다
[3] 하이퍼에서 (3)역에서 (6)역까지 --> [1] 하이퍼에서 [3] 하이퍼로 이동하는데 cnt를 증가시킬 필요없다. 3노드에서 6노드로 이동 했으니 cnt+=1을 한다
[5] 하이퍼에서 (6)역에서 (9)역까지 --> [3] 하이퍼에서 [5] 하이퍼로 이동하는데 cnt를 증가시킬 필요없다. 6노드에서 9노드로 이동했으니 cnt+=1을 한다
이러면 1-3-6-9 로 4번만에 1에서 9로 도착한다.
BFS로 푼 정답 코드