그래프는 정점과 간선으로 이루어져 있다. 두 정점 사이에 경로가 있다면, 두 정점은 연결되어 있다고 한다. 연결 요소는 모든 정점이 서로 연결되어 있는 정점의 부분집합이다. 그래프는 하나 또는 그 이상의 연결 요소로 이루어져 있다.
트리는 사이클이 없는 연결 요소이다. 트리에는 여러 성질이 있다. 예를 들어, 트리는 정점이 n개, 간선이 n-1개 있다. 또, 임의의 두 정점에 대해서 경로가 유일하다.
그래프가 주어졌을 때, 트리의 개수를 세는 프로그램을 작성하시오.
6 3
1 2
2 3
3 4
6 5
1 2
2 3
3 4
4 5
5 6
6 6
1 2
2 3
1 3
4 5
5 6
6 4
0 0
Case 1: A forest of 3 trees.
Case 2: There is one tree.
Case 3: No trees.
from collections import deque
def check(num): # num으로 받은 노드가 트리인지 확인하는 함수
visited[num] = True # 이제 방문함.
queue = deque([num]) # BFS를 위한 queue
while queue:
node = queue.popleft() # 노드 가져옴
for n_node in trees[node]: # bfs. 해당 노드에 연결된 노드들 차례로 가져옴.
if trees[node][n_node] == 0: # 엣지 체크 (0: 체크 안함, 1: 체크함)
if not visited[n_node]: # 해당 노드에 처음 방문
visited[n_node] = True
queue.append(n_node) # 대기열에 다음 노드 추가
trees[node][n_node] = 1 # 엣지 체크
trees[n_node][node] = 1 # 엣지 체크
else:
return False # 헤당 노드에 방문한 적이 있으므로 이는 트리가 아닌 그래프
return True
test = 0
while True:
test += 1
N, M = map(int, input().split())
if N == 0 and M == 0: # 0 0 입력시 종료
break
edges = [list(map(int, input().split())) for _ in range(M)]
visited = [False] * (N + 1) # 방문여부 확인용
trees = [{} for _ in range(N+1)] # 노드 별 연결된 엣지 모음
for e in edges:
trees[e[0]][e[1]] = 0 # 엣지 체크. 0: 체크X / 1: 체크 O
trees[e[1]][e[0]] = 0
cnt = 0 # 트리 갯수
for num in range(1, N + 1): # 모든 노드 확인
if not visited[num]: # 해당 노드 방문 안한 경우
if check(num): # 트리인지 체크함
cnt += 1
# 출력
print("Case {}: ".format(test), end="")
if cnt == 0:
print("No trees.")
elif cnt == 1:
print("There is one tree.")
else:
print("A forest of {} trees.".format(cnt))
python3로 제출하면 시간 초과가 나오고 pypy3로 제출하면 잘 된다.
python3로 하는 방법이 있을지 공부해봐야 함.