๋ค์ํ ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ
- ๊ทธ๋ํ: ๋ ธ๋ + ๊ฐ์
ใด '์๋ก ๋ค๋ฅธ ๊ฐ์ฒด(ํน์ ๊ฐ์ฒด)๊ฐ ์ฐ๊ฒฐ๋์ด ์๋ค'
ใด ์ธ์ ํ๋ ฌ(2์ฐจ์ ๋ฐฐ์ด) - ๋ฉ๋ชจ๋ฆฌ↑, ์๊ฐ↓ / ์ธ์ ๋ฆฌ์คํธ(๋ฆฌ์คํธ) - ๋ฉ๋ชจ๋ฆฌ↓, ์๊ฐ↑
- ๊ทธ๋ํ vs ํธ๋ฆฌ
๊ทธ๋ํ | ํธ๋ฆฌ | |
๋ฐฉํฅ์ฑ | ๋ฐฉํฅ ๊ทธ๋ํ / ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ | ๋ฐฉํฅ ๊ทธ๋ํ |
์ํ์ฑ | ์ํ / ๋น์ํ | ๋น์ํ |
๋ฃจํธ ๋ ธ๋ ์กด์ฌ ์ฌ๋ถ | X | O |
๋ ธ๋๊ฐ ๊ด๊ณ์ฑ | X | ๋ถ๋ชจ-์์ ๊ด๊ณ |
๋ชจ๋ธ์ ์ข ๋ฅ | ๋คํธ์ํฌ ๋ชจ๋ธ | ๊ณ์ธต ๋ชจ๋ธ |
์๋ก์ ์งํฉ
- ์๋ก์ ์งํฉ: ๊ณตํต ์์๊ฐ ์๋ ๋ ์งํฉ
- ์๋ก์ ์งํฉ ์๋ฃ๊ตฌ์กฐ: ์๋ก์ ๋ถ๋ถ ์งํฉ๋ค๋ก ๋๋์ด์ง ์์๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ
ใด union: 2๊ฐ์ ์์๊ฐ ํฌํจ๋ ์งํฉ์ ํ๋์ ์งํฉ์ผ๋ก ํฉ์น๋ ์ฐ์ฐ
ใด find: ํน์ ํ ์์๊ฐ ์ํ ์งํฉ์ด ์ด๋ค ์งํฉ์ธ์ง ์๋ ค์ฃผ๋ ์ฐ์ฐ
# ๊ทธ๋ํ ์ด๋ก
# ๊ธฐ๋ณธ์ ์ธ ์๋ก์ ์งํฉ ์๊ณ ๋ฆฌ์ฆ
# ํน์ ์์๊ฐ ์ํ ์งํฉ ์ฐพ๊ธฐ
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=' ')
- ๋ฃจํธ ๋ ธ๋๊ฐ ๊ฐ์ ์์๋ผ๋ฆฌ๋ ๋์ผํ ์งํฉ์ ์ด๋ฃฌ๋ค. -> {1, 2, 3, 4} / {5, 6}
- ์๊ฐ๋ณต์ก๋ O(VM)
ใด ๋ ธ๋์ ๊ฐ์ V, find ํน์ union ์ฐ์ฐ์ ๊ฐ์ M
ใด ๋ฃจํธ๋ฅผ ์ฐพ๊ธฐ ์ํด ์์๋๋ก ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ์ผ ํจ
- ๊ฒฝ๋ก ์์ถ ๊ธฐ๋ฒ์ ํตํด ์๊ฐ๋ณต์ก๋ ๊ฐ์ -> find ํจ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ ๋ค์ ๋ถ๋ชจ ํ ์ด๋ธ๊ฐ์ ๊ฐฑ์
# ๊ทธ๋ํ ์ด๋ก
# ๊ฐ์ ๋ ์๋ก์ ์งํฉ ์๊ณ ๋ฆฌ์ฆ (๊ฒฝ๋ก ์์ถ ๊ธฐ๋ฒ ์ด์ฉ)
# ๊ฒฝ๋ก ์์ถ ๊ธฐ๋ฒ์ ์ด์ฉํ ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
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
# 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=' ')
- ์๊ฐ๋ณต์ก๋ O(V + M(1 + log(2-M/V)(V))
์๋ก์ ์งํฉ์ ํ์ฉํ ์ฌ์ดํด ํ๋ณ
- ์๋ก์ ์งํฉ์ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ ๋ด์์์ ์ฌ์ดํด์ ํ๋ณํ ๋ ์ฌ์ฉํ ์ ์๋ค.
(๋ฐฉํฅ ๊ทธ๋ํ์์์ ์ฌ์ดํด ์ฌ๋ถ๋ DFS๋ฅผ ์ด์ฉํ์ฌ ํ๋ณ)
# ๊ทธ๋ํ ์ด๋ก
# ์๋ก์ ์งํฉ์ ํ์ฉํ ์ฌ์ดํด ํ๋ณ ์์ค์ฝ๋
# ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
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("์ฌ์ดํด์ด ๋ฐ์ํ์ง ์์์ต๋๋ค.")
์ ์ฅ ํธ๋ฆฌ
- ํ๋์ ๊ทธ๋ํ๊ฐ ์์ ๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ํฌํจํ๋ฉด์ ์ฌ์ดํด์ด ์กด์ฌํ์ง ์๋ ๋ถ๋ถ ๊ทธ๋ํ
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ
# ๊ทธ๋ํ ์ด๋ก
# ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ
# ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
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 edge in edges:
cost, a, b = edge
# ์ฌ์ดํด์ด ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์งํฉ์ ํฌํจ
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
print(result)
- ์๊ฐ ๋ณต์ก๋ O(ElogE)
ใด ๊ฐ์ ์ ์ ๋ ฌํ์ ๋์ ์๊ฐ ๋ณต์ก๋
์์ ์ ๋ ฌ
- ์์๊ฐ ์ ํด์ ธ ์๋ ์ผ๋ จ์ ์์ ์ ์ฐจ๋ก๋๋ก ์ํํด์ผ ํ ๋ ์ฌ์ฉํ ์ ์๋ ์๊ณ ๋ฆฌ์ฆ
- ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ชจ๋ ๋ ธ๋๋ฅผ '๋ฐฉํฅ์ฑ์ ๊ฑฐ์ค๋ฅด์ง ์๋๋ก ์์๋๋ก ๋์ดํ๋ ๊ฒ'
- ๊ทธ๋ํ์์์ ์ ํ๊ด๊ณ๊ฐ ์๋ค๋ฉด, ์์ ์ ๋ ฌ์ ์ํํ์ฌ ๋ชจ๋ ์ ํ ๊ด๊ณ๋ฅผ ์งํค๋ ์ ์ฒด ์์๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
# ๊ทธ๋ํ ์ด๋ก
# ์์ ์ ๋ ฌ
from collections import deque
# ๋
ธ๋์ ๊ฐ์์ ๊ฐ์ ์ ๊ฐ์ ์
๋ ฅ๋ฐ๊ธฐ
v, e = map(int, input().split())
# ๋ชจ๋ ๋
ธ๋์ ๋ํ ์ง์
์ฐจ์๋ 0์ผ๋ก ์ด๊ธฐํ
indegree = [0] * (v+1)
# ๊ฐ ๋
ธ๋์ ์ฐ๊ฒฐ๋ ๊ฐ์ ์ ๋ณด๋ฅผ ๋ด๊ธฐ ์ํ ์ฐ๊ฒฐ ๋ฆฌ์คํธ(๊ทธ๋ํ) ์ด๊ธฐํ
graph = [[] for i in range(v+1)]
# ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ชจ๋ ๊ฐ์ ์ ๋ณด ์
๋ ฅ๋ฐ๊ธฐ
for _ in range(e):
a, b = map(int, input().split())
graph[a].append(b) # ์ ์ A์์ ์ ์ B๋ก ์ด๋ ๊ฐ๋ฅ
# ์ง์
์ฐจ์๋ฅผ 1 ์ฆ๊ฐ
indegree[b] += 1
# ์์ ์ ๋ ฌ ํจ์
def topology_sort():
result = [] # ์๊ณ ๋ฆฌ์ฆ ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ๋ฆฌ์คํธ
q = deque() # ํ ๊ธฐ๋ฅ์ ์ํ deque ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ
# ์ฒ์ ์์ํ ๋๋ ์ง์
์ฐจ์๊ฐ 0์ธ ๋
ธ๋๋ฅผ ํ์ ์ฝ์
for i in range(1, v+1):
if indegree[i] == 0:
q.append(i)
# ํ๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณต
while q:
# ํ์์ ์์ ๊บผ๋ด๊ธฐ
now = q.popleft()
result.append(now)
# ํด๋น ์์์ ์ฐ๊ฒฐ๋ ๋
ธ๋๋ค์ ์ง์
์ฐจ์์์ 1 ๋นผ๊ธฐ
for i in graph[now]:
indegree[i] -= 1
# ์๋กญ๊ฒ ์ง์
์ฐจ์๊ฐ 0์ด ๋๋ ๋
ธ๋๋ฅผ ํ์ ์ฝ์
if indegree[i] == 0:
q.append(i)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
for i in result:
print(i, end=' ')
topology_sort()
- ์๊ฐ ๋ณต์ก๋ O(V + E)
ใด ๋ ธ๋์ ๊ฐ์ ์ ๋ชจ๋ ํ์ธ
์ค์ ๋ฌธ์ 1. ํ ๊ฒฐ์ฑ
# ๊ทธ๋ํ ์ด๋ก
# ์ค์ ๋ฌธ์ 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
n, m = map(int, input().split())
parent = [0] * (n+1)
for i in range(0, n+1):
parent[i] = i
for _ in range(m):
k, a, b = map(int, input().split())
if k == 0:
union_parent(parent, a, b)
else:
if find_parent(parent, a) == find_parent(parent, b):
print("YES")
else:
print("NO")
์ค์ ๋ฌธ์ 2. ๋์ ๋ถํ ๊ณํ
# ๊ทธ๋ํ ์ด๋ก
# ์ค์ ๋ฌธ์ 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
n, m = map(int, input().split())
parent = [0] * (n+1) # ๋ถ๋ชจ ํ
์ด๋ธ
edges = [] # ๋ชจ๋ ๊ฐ์ ์ ๋ด์ ๋ฆฌ์คํธ
result = 0 # ์ต์ข
๋น์ฉ
for i in range(1, n+1):
parent[i] = i
for _ in range(m):
a, b, c = map(int, input().split())
edges.append((c, a, b))
edges.sort()
biggest = 0 # ์ต์ ์ ์ฅ ํธ๋ฆฌ์ ํฌํจ๋๋ ๊ฐ์ ์ค ๊ฐ์ฅ ๋น์ฉ์ด ํฐ ๊ฐ์
for edge in edges:
c, a, b = edge
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += c # ์ต์ข
๊ฒฐ๊ณผ์ ๋น์ฉ ๋ํ๊ธฐ
biggest = c # ๋น์ฉ ์์ผ๋ก ์ ๋ ฌํ๊ธฐ ๋๋ฌธ์ ํ์ฌ์ ๋น์ฉ์ด ๊ฐ์ฅ ํฐ ๋น์ฉ
print(result - biggest) # ์ต์ข
๊ฒฐ๊ณผ์์ ๊ฐ์ฅ ํฐ ๋น์ฉ ๋บด๊ธฐ
์ค์ ๋ฌธ์ 3. ์ปค๋ฆฌํ๋ผ
# ๊ทธ๋ํ ์ด๋ก
# ์ค์ ๋ฌธ์ 2. ์ปค๋ฆฌํ๋ผ
from collections import deque
import copy
n = int(input())
indegree = [0] * (n+1) # ๋ชจ๋ ๋
ธ๋์ ๋ํ ์ง์
์ฐจ์
graph = [[] for i in range(n+1)] # ๋ชจ๋ ๊ฐ์ ์ ๋ํ ์ ๋ณด๋ฅผ ๋ด์ ๋ฆฌ์คํธ
time = [0] * (n+1) # ๊ฐ์ ์๊ฐ
for i in range(1, n+1):
data = list(map(int, input().split()))
time[i] = data[0] # ๊ฐ์ ์๊ฐ
for j in data[1:-1]: # ์ ์ ๊ฐ์
indegree[i] += 1
graph[j].append(i)
def topology_sort():
# ์๊ณ ๋ฆฌ์ฆ ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ๋ฆฌ์คํธ
# ๋ฆฌ์คํธ์ ๊ฒฝ์ฐ, ๋จ์ํ ๋์
์ฐ์ฐ์ ํ๋ฉด ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฆฌ์คํธ์ ๊ฐ์ ๋ณต์ ํด์ ์ฌ์ฉ -> deepcopy
res = copy.deepcopy(time)
# ํ -> deque
q = deque()
for i in range(1, n+1):
if indegree[i] == 0:
q.append(i)
while q:
now = q.popleft()
for i in graph[now]:
indegree[i] -= 1
res[i] = max(res[i], res[now] + time[i])
if indegree[i] == 0:
q.append(i)
for i in range(1, n+1):
print(res[i])
topology_sort()
'๐ค > ์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํฌ ํฌ์ธํฐ (Two Pointers) (0) | 2023.06.13 |
---|---|
์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ (Shortest Path Algorithm) (0) | 2022.04.14 |
๋์ ๊ณํ๋ฒ (Dynamic Programming) (0) | 2022.03.21 |
์ด์ง ํ์ ์๊ณ ๋ฆฌ์ฆ (Binary Search Algorithm) (0) | 2022.02.10 |
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ (Sorting Algorithm) (0) | 2022.02.04 |