We will find a way, we always have.

-interstellar

Problem Solving/λ°±μ€€

[λ°±μ€€] 2887번: ν–‰μ„± 터널 - 파이썬

Redddy 2022. 10. 5. 21:51

πŸ”ˆ 문제

λ•ŒλŠ” 2040λ…„, μ΄λ―Όν˜μ€ μš°μ£Όμ— μžμ‹ λ§Œμ˜ 왕ꡭ을 λ§Œλ“€μ—ˆλ‹€. 왕ꡭ은 $ N $개의 ν–‰μ„±μœΌλ‘œ 이루어져 μžˆλ‹€. λ―Όν˜μ΄λŠ” 이 행성을 효율적으둜 μ§€λ°°ν•˜κΈ° μœ„ν•΄μ„œ 행성을 μ—°κ²°ν•˜λŠ” 터널을 λ§Œλ“€λ €κ³  ν•œλ‹€.
행성은 3차원 μ’Œν‘œμœ„μ˜ ν•œ 점으둜 μƒκ°ν•˜λ©΄ λœλ‹€. 두 ν–‰μ„± $ A(x_{A}, y_{A}, z_{A}) $와 $ B(x_{B}, y_{B}, z_{B}) $λ₯Ό ν„°λ„λ‘œ μ—°κ²°ν•  λ•Œ λ“œλŠ” λΉ„μš©μ€ $ min(\left|x_{A}-x_{B}\right|, \left|y_{A}-y_{B}\right|,\left|z_{A}-z_{B}\right|) $이닀.
λ―Όν˜μ΄λŠ” 터널을 총 $ N-1 $개 κ±΄μ„€ν•΄μ„œ λͺ¨λ“  행성이 μ„œλ‘œ μ—°κ²°λ˜κ²Œ ν•˜λ €κ³  ν•œλ‹€. μ΄λ•Œ, λͺ¨λ“  행성을 ν„°λ„λ‘œ μ—°κ²°ν•˜λŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

πŸ“μž…λ ₯

 μ²«μ§Έ 쀄에 ν–‰μ„±μ˜ 개수 $ N $이 주어진닀. $ \left ( 1 \leq N \leq 100,000 \right ) $ λ‹€μŒ $ N $개 μ€„μ—λŠ” 각 ν–‰μ„±μ˜ x,y,z μ’Œν‘œκ°€ 주어진닀.
μ’Œν‘œλŠ” $ -10^{9} $보닀 ν¬κ±°λ‚˜ κ°™κ³ , $ 10^{9} $보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€. ν•œ μœ„μΉ˜μ— 행성이 두 개 이상 μžˆλŠ” κ²½μš°λŠ” μ—†λ‹€.

 

πŸ“‘μΆœλ ₯

첫째 쀄에 λͺ¨λ“  행성을 ν„°λ„λ‘œ μ—°κ²°ν•˜λŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ„ 좜λ ₯ν•œλ‹€.

 

πŸ“š λ¬Έμ œ ν’€μ΄

λͺ¨λ“  행성에 x, y, z μ’Œν‘œκ°€ 주어진닀.

ν–‰μ„± Aμ—μ„œ ν–‰μ„± B둜 κ°€λŠ” ν„°λ„μ˜ λΉ„μš©μ΄ $ min(\left|x_{A}-x_{B}\right|, \left|y_{A}-y_{B}\right|,\left|z_{A}-z_{B}\right|) $ 이면 Aμ—μ„œ λ‹€λ₯Έ ν–‰μ„±κΉŒμ§€ κ°€λŠ” κ²½λ‘œλ„ λͺ¨λ‘ 확인해야 ν• κΉŒ? 

λŒ€λ‹΅μ€ μ•„λ‹ˆλ‹€.

 

두 μ’Œν‘œμ˜ 차의 μ ˆλŒ€κ°’μ„ μ΅œμ†Œλ‘œ ν•˜λ €λ©΄ μ •λ ¬ν•œ ν›„ λ°”λ‘œ μ•žμ— μžˆλŠ” μ’Œν‘œλž‘ λΉΌλ©΄ μ ˆλŒ€κ°’μ„ μ΅œμ†Œλ‘œ ν•  수 μžˆλ‹€.

λ•Œλ¬Έμ— Aμ—μ„œ λ‹€λ₯Έ ν–‰μ„±κΉŒμ§€ κ°€λŠ” κ²½λ‘œλŠ” x,y,z둜 각각 μ •λ ¬ν–ˆμ„ λ•Œ μ΄μ›ƒν•œ 것듀을 λΊ€ μ ˆλŒ€κ°’μœΌλ‘œ 경둜λ₯Ό 두면 Aμ—μ„œ λ‹€λ₯Έ ν–‰μ„±μœΌλ‘œ κ°€λŠ” λͺ¨λ“  κ²½λ‘œλŠ” 확인할 ν•„μš”μ—†λ‹€. 

 

κ·Έλ ‡κ²Œ μ΅œμ†Œν•œμ˜ 경둜만 담은 λ’€ 크루슀칼 μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ μ΅œμ†Œ μŠ€νŒ¨λ‹ 트리λ₯Ό λ§Œλ“€μ—ˆλ‹€.

 

πŸ’» μ½”λ“œ

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
52
53
54
55
56
57
58
59
60
61
62
63
import sys, heapq
input = sys.stdin.readline
 
def find_parent(parent, x):
    if parent[x] != x:
        parent[x] = find_parent(parent,parent[x])
    return parent[x]
 
 
def union_parent(parent,a,b):
    a = find_parent(parent,a)
    b = find_parent(parent,b)
 
    if a<b:
        parent[b] = a
    else:
        parent[a] = b
 
= int(input())
all_path = []
sort_x = []
sort_y = []
sort_z = []
 
parent = [i for i in range(n)]
 
for i in range(n):
    x,y,z = map(int,input().split())
 
    heapq.heappush(sort_x, [x,y,z,i])
    heapq.heappush(sort_y, [y,z,x,i])
    heapq.heappush(sort_z, [z,x,y,i])
 
pre_x = heapq.heappop(sort_x)
pre_y = heapq.heappop(sort_y)
pre_z = heapq.heappop(sort_z)
 
for _ in range(n-1):
    aft_x = heapq.heappop(sort_x)
    aft_y = heapq.heappop(sort_y)
    aft_z = heapq.heappop(sort_z)
    
    heapq.heappush(all_path, [abs(pre_x[0]-aft_x[0]),pre_x[-1], aft_x[-1]]) # κ°€λŠ” λΉ„μš©, i->j
    heapq.heappush(all_path, [abs(pre_y[0]-aft_y[0]),pre_y[-1], aft_y[-1]])
    heapq.heappush(all_path, [abs(pre_z[0]-aft_z[0]),pre_z[-1], aft_z[-1]])
    pre_x = aft_x
    pre_y = aft_y
    pre_z = aft_z
    
ans = 0
edges = 0
 
while all_path:
    cost, a,b = heapq.heappop(all_path)
    if find_parent(parent,a) != find_parent(parent,b):
        ans += cost
        union_parent(parent,a,b)
        edges += 1
    
    if edges==n-1:
        break
 
print(ans)
cs

 

🍭 μ‹œν–‰μ°©μ˜€

 

ν‹€λ Έλ˜ μ΄μœ λŠ” find_parent() ν•¨μˆ˜ κ΅¬ν˜„ 뢀뢄에 μ‹€μˆ˜κ°€ μžˆμ—ˆλ‹€.

 

πŸ”— 문제링크 ν–‰μ„± 터널

 

2887번: ν–‰μ„± 터널

첫째 쀄에 ν–‰μ„±μ˜ 개수 N이 주어진닀. (1 ≤ N ≤ 100,000) λ‹€μŒ N개 μ€„μ—λŠ” 각 ν–‰μ„±μ˜ x, y, zμ’Œν‘œκ°€ 주어진닀. μ’Œν‘œλŠ” -109보닀 ν¬κ±°λ‚˜ κ°™κ³ , 109보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€. ν•œ μœ„μΉ˜μ— 행성이 두 개 이

www.acmicpc.net