2 minute read

16947번 : 서울 지하철 2호선

문제 링크

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

문제 설명

서울 지하철 2호선은 다음과 같이 생겼다.

그림1

지하철 2호선에는 51개의 역이 있고, 역과 역 사이를 연결하는 구간이 51개 있다. 즉, 정점이 51개이고, 양방향 간선이 51개인 그래프로 나타낼 수 있다. 2호선은 순환선 1개와 2개의 지선으로 이루어져 있다. 한 역에서 출발해서 계속 가면 다시 출발한 역으로 돌아올 수 있는 노선을 순환선이라고 한다. 지선은 순환선에 속하는 한 역에서 시작하는 트리 형태의 노선이다.

두 역(정점) 사이의 거리는 지나야 하는 구간(간선)의 개수이다. 역 A와 순환선 사이의 거리는 A와 순환선에 속하는 역 사이의 거리 중 최솟값이다.

지하철 2호선과 같은 형태의 노선도가 주어졌을 때, 각 역과 순환선 사이의 거리를 구해보자.

입력

첫째 줄에 역의 개수 N(3 ≤ N ≤ 3,000)이 주어진다. 둘째 줄부터 N개의 줄에는 역과 역을 연결하는 구간의 정보가 주어진다. 같은 구간이 여러 번 주어지는 경우는 없고, 역은 1번부터 N번까지 번호가 매겨져 있다. 임의의 두 역 사이에 경로가 항상 존재하는 노선만 입력으로 주어진다.

출력

총 N개의 정수를 출력한다. 1번 역과 순환선 사이의 거리, 2번 역과 순환선 사이의 거리, …, N번 역과 순환선 사이의 거리를 공백으로 구분해 출력한다.

문제풀이

순환선 노선을 산출하는 건 dfs, 순환선과 아닌 노선의 거리를 구하는 건 bfs를 활용하여 문제를 풀이하였다.

# 최대 재귀 횟수를 늘려야 해당 문제에서 recursion error 발생하지 않음
from collections import deque
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

# 순환선 노선들 산출하는 함수
temp = [0]
def get_circulation_lines(curLine) :
    global circulationLines
    # 현재까지 경로가 아닌 노선들 중에서 다음 노선들만 뽑기
    temp.append(curLine)
    nextLines = [i for i in graph[curLine] if i != temp[-2]]

    for next in nextLines:
        # 이미 순환선 정보를 찾았으면 다음 재귀는 모두 나가기
        if circulationLines :
            break

        # 현재까지 경로에 있던 노선들 중에서 다음 노선이 있을 경우 순환선으로 확인하고 저장
        if next in temp : 
            start = temp.index(next)
            circulationLines = temp[start:].copy()
            return

        # 아닐 경우에는 다음 노선 정보 탐색
        else :
            get_circulation_lines(next)
            temp.pop()

# 현재 노선과 순환선 사이의 거리를 산출하는 함수
def get_distance(curLine) :
    deq = deque([[curLine]])

    while deq :
        temp = deq.popleft()
        nextLines = graph[temp[-1]]

        for next in nextLines :
            # 다음 노선이 순환선이면 현재까지 탐색 길이 리턴
            if next in circulationLines :
                return len(temp)
            # 다음 노선이 현재까지 노선들 중에 없을 경우만 deque에 넣기 
            elif next not in temp : 
                deq.append(temp+[next])

N = int(input())
graph = [[] for _ in range(N+1)]
distances = [0 for _ in range(N+1)]
circulationLines = []

# 양방향 그래프 정보 저장
for _ in range(N) :
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

# 순환선 노선 산출 (들어가는 숫자는 1~N까지 상관없음)
get_circulation_lines(1)

# 순환선이 아닌 노선들만 거리를 구하기
for i in range(1, N+1) :
    if i not in circulationLines :
        distances[i] = get_distance(i)

# 답안 출력
print(*distances[1:])

Comments