문제 접근 및 공부 내용, 풀이는 모두 하단 코드에 "주석"으로 포함되어 있으니 참고해주세요.
문제 유형 보기
더보기
https://www.acmicpc.net/problem/20040유니온파인드
풀이
import sys
input = sys.stdin.readline
# 0 ~ n-1 점 n개 주어짐
# 어느 세 점도 일직선 위에 놓이지 x.
# 매 차례 두 점 선택 긋는데, 교차는 가능.
# 사이클 완성 시 게임이 종료됨.
# 이전에 그은 선분만 다시 못 그을 뿐, 이미 뽑은 점 재선택은 가능
# 입력 : 점의 개수 n, 진행된 차례 수 m
# 출력 : m차례까지 게임 진행 후 사이클 만들어졌다면 만들어진 차례 번호 출력,
# 안만들어졌으면 0을 출력.
# 출력 단계는 1부터 시작해서 m까지임에 유의.
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
x_root = find(x)
y_root = find(y)
if x_root == y_root:
# 이 두 점(x, y)를 이으면 사이클이 생기니,
# 잇지 마!! 하는 의미로 False 반환
return False
if rank[x_root] > rank[y_root]:
parent[y_root] = x_root
elif rank[y_root] > rank[x_root]:
parent[x_root] = y_root
else:
parent[y_root] = x_root
rank[x_root] += 1
return True
n, m = map(int, input().split())
parent = list(range(n))
rank = [0] * n
for stage in range(1, m + 1):
x, y = map(int, input().split())
if not union(x, y): # 사이클이 생기면 잇지 말라고 False 반환하게 만들자.
print(stage)
break
else:
print(0)
강사님 풀이 들으며 필기
import sys
input = sys.stdin.readline
# 이 문제는 '사이클' 키워드가 등장했으니, 유니온 파인드를 떠올릴 수 있어야함.
# 사이클은 유니온 파인드의 대표 소재.
def find(x):
if x != parent[x]:
parent[x] = find(parent[x])
return parent[x] # 사실상 x 반환해도 같음
def union(x, y):
x_root = find(x)
y_root = find(y)
# 루트가지고 통합을 해야 두 집합이 통합이 되니까.
# 중간 꺼 가지고 붙여버리면 끊겨버릴 수 있으니까.
# 원래 코드에도 있던 부분이었지만, 여기서는 이게 사이클을 판별하는 로직으로도 작동함.
# 일종의 백트래킹.
if x_root == y_root:
return False
if rank[x_root] > rank[y_root]:
parent[y_root] = x_root
# 이렇게 랭크가 큰 노드한테 작은 노드를 붙여주는 이유:
# 그렇게 붙여야 트리가 최대한 안정적인 구조를 유지해서
# 높이가 최대한 작게 됨.
elif rank[x_root] < rank[y_root]:
parent[x_root] = y_root
else:
parent[x_root] = y_root
rank[y_root] += 1
return True
n, m = map(int, input().split())
parent = list(range(n))
rank = [0] * n
for t in range(1, m + 1):
x, y = map(int, input().split())
# union
# union이 제대로 되었으면 -> 넘어감
# union이 제대로 되지 않았으면 -> 사이클 발생 알리고 종료
if not union(x, y):
# union이 제대로 되면 True가 반환되어 나가도록 짤 거임.
print(t)
break
# 파이썬 if else indentation 테크닉
else:
print(0)
'Algorithms & Languages > 파이썬 알고리즘 문제풀이' 카테고리의 다른 글
[Python/백준] 1647. 도시 분할 계획 (0) | 2025.02.28 |
---|---|
[Python/DailyAlgo, 백준] 86. 최소 신장 트리, 1197. 최소 스패닝 트리, 89. 동기화 서버 구축 (0) | 2025.02.27 |
[Python/백준] 1717. 집합의 표현 (0) | 2025.02.27 |
[Python/DailyAlgo] 93. 게으름뱅이 (0) | 2025.02.26 |
[Python/프로그래머스] 42626. 더 맵게 (0) | 2025.02.26 |