[ μ΄κ²μ΄ μ½λ©ν μ€νΈλ€ with νμ΄μ¬ ] κΈ°ν κ·Έλν μ΄λ‘
• μλ‘μ μ§ν© (Disjoint Sets) : κ³΅ν΅ μμκ° μλ λ μ§ν©μ μλ―Έν©λλ€.
• μλ‘μ λΆλΆ μ§ν©λ€λ‘ λλμ΄μ§ μμλ€μ λ°μ΄ν°λ₯Ό μ²λ¦¬νκΈ° μν μλ£κ΅¬μ‘°μ λλ€.
• μλ‘μ μ§ν© μλ£κ΅¬μ‘°λ λ μ’ λ₯μ μ°μ°μ μ§μν©λλ€.
• ν©μ§ν©(Union) : λ κ°μ μμκ° ν¬ν¨λ μ§ν©μ νλμ μ§ν©μΌλ‘ ν©μΉλ μ°μ°μ λλ€.
• μ°ΎκΈ°(Find) : νΉμ ν μμκ° μν μ§ν©μ΄ μ΄λ€ μ§ν©μΈμ§ μλ €μ£Όλ μ°μ°μ λλ€.
• μλ‘μ μ§ν© μλ£κ΅¬μ‘°λ ν©μΉκΈ° μ°ΎκΈ°(Union Find) μλ£κ΅¬μ‘°λΌκ³ λΆλ¦¬κΈ°λ ν©λλ€.
• μ¬λ¬ κ°μ ν©μΉκΈ° μ°μ°μ΄ μ£Όμ΄μ‘μ λ μλ‘μ μ§ν© μλ£κ΅¬μ‘°μ λμ κ³Όμ μ λ€μκ³Ό κ°μ΅λλ€.
1. ν©μ§ν©(Union) μ°μ°μ νμΈνλ©°, μλ‘ μ°κ²°λ λ λ Έλ A, Bλ₯Ό νμΈν©λλ€.
1) Aμ Bμ λ£¨νΈ λ Έλ A', B' λ₯Ό κ°κ° μ°Ύμ΅λλ€.
2) A'λ₯Ό B'μ λΆλͺ¨λ Έλλ‘ μ€μ ν©λλ€.
2. λͺ¨λ ν©μ§ν©(Union) μ°μ°μ μ²λ¦¬ν λκΉμ§ 1λ²μ κ³Όμ μ λ°λ³΅ν©λλ€.
1. κΈ°λ³Έμ μΈ μλ‘μ μ§ν© ꡬν λ°©λ²
# κΈ°λ³Έμ μΈ μλ‘μ μ§ν© μκ³ λ¦¬μ¦
# νΉμ μμκ° μν μ§ν©μ μ°ΎκΈ°
def find_parent(parent, x):
# λ£¨νΈ λ
Έλκ° μλλΌλ©΄, λ£¨νΈ λ
Έλλ₯Ό μ°Ύμ λκΉμ§ μ¬κ·μ μΌλ‘ νΈμΆ
if parent[x] != x:
return find_parent(parent, parent[x])
return 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
# λ
Έλμ κ°μμ κ°μ (union μ°μ°)μ κ°μ μ
λ ₯λ°κΈ°
v, e = map(int, input().split())
parent = [0] * (v+1) # λΆλͺ¨ ν
μ΄λΈ μ΄κΈ°ν
# λΆλͺ¨ ν
μ΄λΈμμ, λΆλͺ¨λ₯Ό μκΈ° μμ μΌλ‘ μ΄κΈ°ν
for i in range(1, v+1):
parent[i] = i
# union μ°μ°μ κ°κ° μν
for i in range(e):
a, b = map(int, input().split())
union_parent(parent, a, b)
# κ° μμκ° μν μ§ν© μΆλ ₯
print('κ° μμκ° μν μ§ν©: ', end='')
for i in range(1, v+1):
print(find_parent(parent, i), end=' ')
print()
# λΆλͺ¨ ν
μ΄λΈ λ΄μ© μΆλ ₯
print('λΆλͺ¨ ν
μ΄λΈ: ', end='')
for i in range(1, v+1):
print(parent[i], end=' ')
• ν©μ§ν©(Union) μ°μ°μ΄ νΈν₯λκ² μ΄λ£¨μ΄μ§λ κ²½μ° μ°ΎκΈ°(Find) ν¨μκ° λΉν¨μ¨μ μΌλ‘ λμν©λλ€.
• μ΅μ μ κ²½μ°μλ μ°ΎκΈ°(Find) ν¨μκ° λͺ¨λ λ Έλλ₯Ό λ€ νμΈνκ² λμ΄ μκ° λ³΅μ‘λκ° O(V)μ λλ€.
κ²½λ‘ μμΆ
• μ°ΎκΈ°(Find) ν¨μλ₯Ό μ΅μ ννκΈ° μν λ°©λ²μΌλ‘ κ²½λ‘ μμΆ(Path Compression)μ μ΄μ©ν μ μμ΅λλ€.
• μ°ΎκΈ°(Find) ν¨μλ₯Ό μ¬κ·μ μΌλ‘ νΈμΆν λ€μ λΆλͺ¨ ν μ΄λΈ κ°μ λ°λ‘ κ°±μ ν©λλ€.
# νΉμ μμκ° μν μ§ν©μ μ°ΎκΈ°
def find_parent(parent, x):
# λ£¨νΈ λ
Έλκ° μλλΌλ©΄, λ£¨νΈ λ
Έλλ₯Ό μ°Ύμ λκΉμ§ μ¬κ·μ μΌλ‘ νΈμΆ
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
• κ²½λ‘ μμΆ κΈ°λ²μ μ μ©νλ©΄ κ° λ Έλμ λνμ¬ μ°ΎκΈ°(Find) ν¨μλ₯Ό νΈμΆν μ΄νμ ν΄λΉ λ Έλμ 루νΈλ Έλκ° λ°λ‘ λΆλͺ¨ λ Έλκ° λ©λλ€.
• λμΌν μμμ λν΄μ λͺ¨λ ν©μ§ν©(Union) ν¨μλ₯Ό μ²λ¦¬ν ν κ° μμμ λνμ¬ μ°ΎκΈ°(Find) ν¨μλ₯Ό μννλ©΄ λ€μκ³Ό κ°μ΄ λΆλͺ¨ ν μ΄λΈμ΄ κ°±μ λ©λλ€.
• κΈ°λ³Έμ μΈ λ°©λ²μ λΉνμ¬ μκ°λ³΅μ‘λκ° κ°μ λ©λλ€.
1-1. μλ‘μ μ§ν©μ νμ©ν μ¬μ΄ν΄ νλ³
• μλ‘μ μ§ν©μ 무방ν₯ κ·Έλν λ΄μμ μ¬μ΄ν΄μ νλ³ν λ μ¬μ©ν μ μμ΅λλ€.
• μ°Έκ³ λ‘ λ°©ν₯ κ·Έλνμμμ μ¬μ΄ν΄ μ¬λΆλ DFSλ₯Ό μ΄μ©νμ¬ νλ³ν μ μμ΅λλ€.
• μ¬μ΄ν΄ νλ³ μκ³ λ¦¬μ¦μ λ€μκ³Ό κ°μ΅λλ€.
1. κ° κ°μ μ νλμ© νμΈνλ©° λ λ Έλμ λ£¨νΈ λ Έλλ₯Ό νμΈν©λλ€.
1) λ£¨νΈ λ Έλκ° μλ‘ λ€λ₯΄λ€λ©΄ λ λ Έλμ λνμ¬ ν©μ§ν©(Union) μ°μ°μ μνν©λλ€.
2) λ£¨νΈ λ Έλκ° μλ‘ κ°λ€λ©΄ μ¬μ΄ν΄(Cycle)μ΄ λ°μν κ²μ λλ€.
2. κ·Έλνμ ν¬ν¨λμ΄ μλ λͺ¨λ κ°μ μ λνμ¬ 1λ² κ³Όμ μ λ°λ³΅ν©λλ€.
# νΉμ μμκ° μν μ§ν©μ μ°ΎκΈ°
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
# λ
Έλμ κ°μμ κ°μ (union μ°μ°)μ κ°μ μ
λ ₯λ°κΈ°
v, e = map(int, input().split())
parent = [0]*(v+1) # λΆλͺ¨ν
μ΄λΈ μ΄κΈ°ν
# λΆλͺ¨ ν
μ΄λΈμμμ, λΆλͺ¨λ₯Ό μκΈ° μμ μΌλ‘ μ΄κΈ°ν
for i in range(1, v+1):
parent[i] = i
cycle = False # μ¬μ΄ν΄ λ°μ μ¬λΆ
for i in range(e):
a, b = map(int, input().split())
# μ¬μ΄ν΄μ΄ λ°μν κ²½μ° μ’
λ£
if find_parent(parent, a) == find_parent(parent, b):
cycle = True
break
# μ¬μ΄ν΄μ΄ λ°μνμ§ μμλ€λ©΄ ν©μ§ν©(union) μν
else:
union_parent(parent, a, b)
if cycle:
print("μ¬μ΄ν΄μ΄ λ°μνμ΅λλ€.")
else:
print("μ¬μ΄ν΄μ΄ λ°μνμ§ μμμ΅λλ€.")
• μ μ₯νΈλ¦¬ : κ·Έλνμμ λͺ¨λ λ Έλλ₯Ό ν¬ν¨νλ©΄μ μ¬μ΄ν΄μ΄ μ‘΄μ¬νμ§ μλ λΆλΆ κ·Έλνλ₯Ό μλ―Έν©λλ€.
• λͺ¨λ λ Έλκ° ν¬ν¨λμ΄ μλ‘ μ°κ²°λλ©΄μ μ¬μ΄ν΄μ΄ μ‘΄μ¬νμ§ μλλ€λ 쑰건μ νΈλ¦¬μ 쑰건μ΄κΈ°λ ν©λλ€.
μ΅μμ μ₯ νΈλ¦¬
• μ΅μνμ λΉμ©μΌλ‘ ꡬμ±λλ μ μ₯ νΈλ¦¬λ₯Ό μ°ΎμμΌ ν λ μ΄λ»κ² ν΄μΌ ν κΉμ?
• μλ₯Ό λ€μ΄ Nκ°μ λμκ° μ‘΄μ¬νλ μν©μμ λ λμ μ¬μ΄μ λλ‘λ₯Ό λμ μ 체 λμκ° μλ‘ μ°κ²°λ μ μκ² λλ‘λ₯Ό μ€μΉνλ κ²½μ°λ₯Ό μκ°ν΄λ΄ μλ€.
• λ λμ A, Bλ₯Ό μ ννμ λ Aμμ Bλ‘ μ΄λνλ κ²½λ‘κ° λ°λμ μ‘΄μ¬νλλ‘ λλ‘λ₯Ό μ€μΉν©λλ€.
ν¬λ£¨μ€μΉΌ μκ³ λ¦¬μ¦
• λνμ μΈ μ΅μ μ μ₯ νΈλ¦¬ μκ³ λ¦¬μ¦μ λλ€.
• 그리λ μκ³ λ¦¬μ¦μΌλ‘ λΆλ₯λ©λλ€.
• ꡬ체μ μΈ λμκ³Όμ μ λ€μκ³Ό κ°μ΅λλ€.
1. κ°μ λ°μ΄ν°λ₯Ό λΉμ©μ λ°λΌ μ€λ¦μ°¨μμΌλ‘ μ λ ¬ν©λλ€.
2. κ°μ μ νλμ© νμΈνλ©° νμ¬μ κ°μ μ΄ μ¬μ΄ν΄μ λ°μμν€λμ§ νμΈν©λλ€.
1) μ¬μ΄ν΄μ΄ λ°μνμ§ μλ κ²½μ° μ΅μ μ μ₯νΈλ¦¬μ ν¬ν¨μν΅λλ€.
2) μ¬μ΄ν΄μ΄ λ°μνλ κ²½μ° μ΅μ μ μ₯νΈλ¦¬μ ν¬ν¨μν€μ§ μμ΅λλ€.
3. λͺ¨λ κ°μ μ λνμ¬ 2λ²μ κ³Όμ μ λ°λ³΅ν©λλ€.
# νΉμ μμκ° μν μ§ν©μ μ°ΎκΈ°
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
# λ
Έλμ κ°μμ κ°μ (union μ°μ°)μ κ°μ μ
λ ₯λ°κΈ°
v, e = map(int, input().split())
parent = [0] * (v+1) # λΆλͺ¨ ν
μ΄λΈ μ΄κΈ°ν
# λͺ¨λ κ°μ μ λ΄μ 리μ€νΈμ μ΅μ’
λΉμ©μ λ΄μ λ³μ
edges = []
result = 0
# λΆλͺ¨ ν
μ΄λΈ μμμ, λΆλͺ¨λ₯Ό μκΈ° μμ μΌλ‘ μ΄κΈ°ν
for i in range(1, v+1):
parent[i] = i
# λͺ¨λ κ°μ μ λν μ 보λ₯Ό μ
λ ₯λ°κΈ°
for _ in range(e):
a, b, cost = map(int, input().split())
# λΉμ©μμΌλ‘ μ λ ¬νκΈ° μν΄μ ννμ 첫 λ²μ§Έ μμλ₯Ό λΉμ©μΌλ‘ μ€μ
edges.append((cost, a, b))
# κ°μ μ λΉμ©μμΌλ‘ μ λ ¬
edges.sort()
# κ°μ μ νλμ© νμΈνλ©°
for edges in edges:
cost, a, b = edges
# μ¬μ΄ν΄μ΄ λ°μνμ§ μλ κ²½μ°μλ§ μ§ν©μ ν¬ν¨
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
print(result)
• ν¬λ£¨μ€μΉΌ μκ³ λ¦¬μ¦μ κ°μ μ κ°μκ° Eκ°μΌ λ, O(ElogE)μ μκ° λ³΅μ‘λλ₯Ό κ°μ§λλ€.
• ν¬λ£¨μ€μΉΌ μκ³ λ¦¬μ¦μμ κ°μ₯ λ§μ μκ°μ μꡬνλ κ³³μ κ°μ μ μ λ ¬μ μννλ λΆλΆμ λλ€.
• νμ€ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ΄μ©ν΄ Eκ°μ λ°μ΄ν°λ₯Ό μ λ ¬νκΈ° μν μκ° λ³΅μ‘λλ O(ElogE) μ λλ€.
κ°μ λ° μΆμ²