- [백준] 1717번 집합의 표현 Python 파이썬 풀이2023년 01월 16일
- Cat_Code
- 작성자
- 2023.01.16.:11
1717번: 집합의 표현
첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는
www.acmicpc.net
[문제]
[코드]
import sys sys.setrecursionlimit(1000000) input = sys.stdin.readline n, m = map(int, input().split()) parent = [i for i in range(n + 1)] def find_parent(x): if parent[x] != x: parent[x] = find_parent(parent[x]) return parent[x] def union_parent(a, b): a = find_parent(a) b = find_parent(b) if a < b: parent[b] = a else: parent[a] = b for _ in range(m): command, a, b = map(int, input().split()) if command == 0: union_parent(a, b) else: if find_parent(a) == find_parent(b): print("YES") else: print("NO")
[해설]
백준의 자료구조 문제중 골드4에 해당하는 문제이다.
초반 구조 설계만 잘한다면 쉽게 풀수 있는 문제이다.
이 문제의 핵심은 다음과 같다
1. 두 집합이 어디에 속해있는 찾는 방법
2. 두 집합을 합치는 방법import sys sys.setrecursionlimit(1000000) input = sys.stdin.readline n, m = map(int, input().split()) parent = [i for i in range(n + 1)]
재귀함수를 활용할 것이기 때문에 재귀함수의 깊이를 지정해준다.
그리고 n,m 변수를 받아주고
처음 parent 리스트를 생성하여 초기 집합을 구성해준다.
ex) 출력1
parent = [ [0], [1], [2], [3] ... [7] ]
def find_parent(x): if parent[x] != x: parent[x] = find_parent(parent[x]) return parent[x]
첫 번째로 만들어 줄 함수는 find_parent이다.
즉, 부모 집합을 탐색해주는 함수이다.
만약 parent[x]가 x와 같다면 parent[x] 그대로 리턴하면되고
다른 경우 (이부분은 직접 생각하지 않으면 이해하기 힘들수 있다)
다시 재귀함수를 통해서 부모를 찾아나가는 것이다.
def union_parent(a, b): a = find_parent(a) b = find_parent(b) if a < b: parent[b] = a else: parent[a] = b
이 부분은 2번째 문제인 합집합을 만드는 함수로
부모를 찾고 이를 통해서 b가 크다면 parent[b]의 부모를 a로 지정하고 다른 경오 parent[a]의 부모를 b로 지정하는것이다.
두 함수를 적용해서
예를 들어 쉽게 설명하자면
ex) 예제1
i)
초기 parent
x 0 1 2 3 4 5 6 7 부모 0 1 2 3 4 5 6 7 0 1 3
0 = 합집합 (union_parent(1, 3)
find_parent(1) == 1
find_parent(3) == 3
따라서
parent[3] == 1
x 0 1 2 3 4 5 6 7 부모 0 1 2 1 4 5 6 7 ii)
1 1 7
1 = 부모가 같은지 판단
find_parent(1) == 1
find_parent(7) == 7
1 != 7
따라서 No
이런식으로 부모와 x값이 다른 경우에는 다시 재귀를 통해서 부모값의 부모를 찾아가면된다.
위 메커니즘이 이 문제의 핵심이다.
따라서 이러한 계산을 반복하여
for문으로 표현하면 아래와 같다
for _ in range(m): command, a, b = map(int, input().split()) if command == 0: union_parent(a, b) else: if find_parent(a) == find_parent(b): print("YES") else: print("NO")
command가 0일경우 합집합을 만들고
1 일경우 a,b의 부모를 비교하여 같은 경우 YES를
다른경우 NO를 출력한다.
'[연습의 흔적들] > 백준⚾' 카테고리의 다른 글
[백준]9934번 완전 이진 트리 파이썬(Python) 풀이 (1) 2023.03.14 [백준]1991번 트리 순회 풀이 (0) 2023.03.13 [백준] 1339번 단어수학 Python 파이썬 풀이 (0) 2023.01.15 [백준] 1038번 감소하는 수 파이썬(Python) 풀이 (0) 2022.12.22 [백준] 10844번 쉬운 계단 수 파이썬(Python) 풀이 (0) 2022.12.19 다음글이전글이전 글이 없습니다.댓글