Algorithm 문제
[백준] 13306 - 트리
노예2
2019. 6. 27. 13:13
https://www.acmicpc.net/problem/13306
13306번: 트리
표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 트리의 정점의 개수와 질의의 개수를 나타내는 두 정수 N과 Q (1 ≤ N, Q ≤ 200,000)가 주어진다. 다음 N-1개의 줄의 i번째 줄에는 정점 i+1의 부모 정점을 나타내는 정수 a가 주어진다 (1 ≤ a ≤ N). 다음 (N-1)+Q개의 줄 중에서 N-1개는 (1)의 형태로, Q개는 (2)의 형태로 주어진다. (1) 두 정수 x와 b가 주어진다(x = 0, 2 ≤ b ≤ N). 이것은 b의
www.acmicpc.net
일반적인 방법으로 UNION-FIND TREE 를 사용할 경우 edge 삭제 후 부모 갱신 과정에서 시간초과가 발생한다. 삭제된 edge 의 하위에 있는 노드의 모든 부모를 갱신해야 하므로 오버헤드가 크다.
edge 를 추가하며 부모를 갱신할 경우, 앞선 경우에서의 오버헤드를 줄일 수 있다.
단, 결과가 반대로 얻으므로 저장 후, 역순으로 출력해야 한다.
<python 코드>
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
|
import sys
inp = sys.stdin.readlines()
n, q = tuple(map(int, inp[0].split()))
parent = [i for i in range(n+1)]
result = []
for q in inp[n:][::-1]:
q = q.split()
if len(q) == 2:
parent[int(q[1])] = int(inp[int(q[1]) - 1])
else:
a, b = int(q[1]), int(q[2])
p_a, p_b = parent[a], parent[b]
while(True):
if parent[p_a] == p_a:
parent[a] = p_a
break
p_a = parent[p_a]
while(True):
if parent[p_b] == p_b:
parent[b] = p_b
break
p_b = parent[p_b]
if p_a == p_b:
result.append(True)
else:
result.append(False)
for re in result[::-1]:
if re:
print('YES')
else:
print('NO')
|
cs |