백준 문제풀이

백준 17469 - 트리의 색깔과 쿼리 [Python]

Vermeil 2021. 5. 17. 18:40

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

 

17469번: 트리의 색깔과 쿼리

N개의 정점으로 구성된 트리가 있다. 각 정점은 1번부터 N번까지 번호가 매겨져있고, 1 이상 10만 이하의 자연수로 표현되는 색깔을 하나 갖고 있다. 루트는 1번 정점이고, 트리이기 때문에 임의

www.acmicpc.net

 

[사용한 알고리즘]

Smaller to Larger Technique

 

 

https://justicehui.github.io/medium-algorithm/2019/09/23/small-to-large/

이 글을 통해 공부했습니다

 

 

 

1. 쿼리를 뒤집는다.

2. 그러면 간선 제거를 간선 연결로 볼 수 있다. 그럼 엄청 쉬워진다

 

 

Union-Find를 통해 구현했고, 말 그대로 작은거를 큰거에 넣으면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import sys
 
input = sys.stdin.readline
 
= [i for i in range(101010)]
 
 
def find(x):
    if x == p[x]:
        return x
    p[x] = find(p[x])
    return p[x]
 
 
def union(x, y):  # 작은거 x 큰거 y
    x = find(x)
    y = find(y)
    if len(c[y]) <= len(c[x]):
        x, y = y, x
    p[x] = y
    for i in c[x]:
        c[y].add(i)
    c[x].clear()
 
 
n, qs = map(int, input().split())
= [0 for _ in range(101010)]
= [set() for _ in range(101010)]
for i in range(2, n + 1):
    g[i] = int(input())
 
for i in range(1, n + 1):
    c[i].add(int(input()))
 
= []
for i in range(n + qs - 1):
    a, b = map(int, input().split())
    q.append((a, b))
 
ans = []
q.reverse()
for a, b in q:
    if a == 1:
        union(b, g[b])
    else:
        ans.append(len(c[find(b)]))
 
ans.reverse()
for i in ans:
    print(i)
 
cs