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

from collections import deque
def find_cycle(n, adj):
visited = [False] * (n + 1)
parent = [0] * (n + 1)
cycle = []
def dfs(u, prev):
nonlocal cycle
visited[u] = True
for v in adj[u]:
if v == prev:
continue
if not visited[v]:
parent[v] = u
if dfs(v, u):
return True
else:
# 사이클을 찾았을 때
if not cycle:
# 현재 노드 u부터 v까지의 경로를 사이클로 기록
cycle = []
temp = u
cycle.append(v)
while temp != v:
cycle.append(temp)
temp = parent[temp]
return True
return False
dfs(1, -1)
return cycle
def compute_distances(n, adj, cycle_nodes):
distances = [-1] * (n + 1)
q = deque()
# 순환선에 속하는 노드들의 거리는 0
for node in cycle_nodes:
distances[node] = 0
q.append(node)
# BFS를 통해 거리 계산
while q:
current = q.popleft()
for neighbor in adj[current]:
if distances[neighbor] == -1:
distances[neighbor] = distances[current] + 1
q.append(neighbor)
return distances[1:] # 1번부터 출력
def main():
import sys
sys.setrecursionlimit(10000)
input = sys.stdin.readline
n = int(input())
adj = [[] for _ in range(n + 1)]
for _ in range(n):
u, v = map(int, input().split())
adj[u].append(v)
adj[v].append(u)
cycle = find_cycle(n, adj)
distances = compute_distances(n, adj, cycle)
print(' '.join(map(str, distances)))
if __name__ == "__main__":
main()
def find_cycle(n, adj):
visited = [False] * (n + 1)
parent = [0] * (n + 1)
cycle = []
def dfs(u, prev):
nonlocal cycle
visited[u] = True
for v in adj[u]:
if v == prev:
continue
if not visited[v]:
parent[v] = u
if dfs(v, u):
return True
else:
# 사이클을 찾았을 때
if not cycle:
# 현재 노드 u부터 v까지의 경로를 사이클로 기록
cycle = []
temp = u
cycle.append(v)
while temp != v:
cycle.append(temp)
temp = parent[temp]
return True
return False
dfs(1, -1)
return cycle
visited: 각 노드의 방문 여부를 기록합니다.parent: 각 노드의 부모 노드를 기록하여 사이클을 추적합니다.cycle 리스트에 저장합니다.prev)를 제외한 인접 노드를 탐색합니다.cycle 리스트에 저장합니다.def compute_distances(n, adj, cycle_nodes):
distances = [-1] * (n + 1)
q = deque()
# 순환선에 속하는 노드들의 거리는 0
for node in cycle_nodes:
distances[node] = 0
q.append(node)
# BFS를 통해 거리 계산
while q:
current = q.popleft()
for neighbor in adj[current]:
if distances[neighbor] == -1:
distances[neighbor] = distances[current] + 1
q.append(neighbor)
return distances[1:] # 1번부터 출력
distances: 각 노드의 순환선까지의 거리를 저장하는 리스트입니다. 초기값은 1로 설정합니다.0으로 설정합니다.def main():
import sys
sys.setrecursionlimit(10000)
input = sys.stdin.readline
n = int(input())
adj = [[] for _ in range(n + 1)]
for _ in range(n):
u, v = map(int, input().split())
adj[u].append(v)
adj[v].append(u)
cycle = find_cycle(n, adj)
distances = compute_distances(n, adj, cycle)
print(' '.join(map(str, distances)))
if __name__ == "__main__":
main()
N과 연결 정보를 입력받아 인접 리스트(adj)를 구성합니다.find_cycle 함수를 호출하여 순환선을 구성하는 노드들을 찾습니다.compute_distances 함수를 호출하여 각 노드의 순환선까지의 거리를 계산합니다.find_cycle):O(N)입니다.compute_distances):O(N)입니다.O(N) + O(N) = O(N), 여기서 N은 최대 3,000이므로 효율적입니다.O(N) 공간을 사용합니다.O(N) 공간을 사용합니다.O(N)입니다.adj):adj[1] = [2, 3]은 노드 1이 노드 2와 3에 연결되어 있음을 의미합니다.deque):popleft()와 append() 연산이 O(1) 시간에 수행됩니다.visited, parent, distances):visited: DFS에서 노드의 방문 여부를 기록합니다.parent: DFS에서 노드의 부모를 기록하여 사이클을 추적합니다.distances: BFS에서 각 노드의 순환선까지의 거리를 기록합니다.