์ ๋์จํ์ธ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋
โ ์๋ก์ ์งํฉ(Disjoint Set)
โ ์ฌ๋ฌ ๊ฐ์ ๋
ธ๋๊ฐ ์กด์ฌํ ๋ , ์์์ ๋ ๋
ธ๋๊ฐ ๊ฐ์ ๊ทธ๋ํ์ ์ํด์๋์ง ํ๋ณ
Union & Find
- Find
๋ ธ๋ x๊ฐ ํฌํจ๋ ์งํฉ์ ์ฐพ๋ ์ฐ์ฐ
def find_parent(parent, current):
if parent[current] != current:
return find_parent(parent, parent[current])
return current
- Union
๋ ธ๋ x๊ฐ ํฌํจ๋ ์งํฉ๊ณผ ๋ ธ๋ y๊ฐ ํฌํจ๋ ๋ ์งํฉ์ ํตํฉํ๋ ์ฐ์ฐ
def union_parent(parent, x, y):
x = find_parent(parent, x)
y = find_parent(parent, y)
# ๋จ์ํ ํํ์์๋ ์์ ์ชฝ์ผ๋ก ํฉ์น๋ค.
if x < y:
parent[y] = x
else:
parent[x] = y
์ฝ๋ ์์
# ๋
ธ๋์ ๊ฐ์ (union ์ฐ์ฐ) ๊ฐ์
node, edge = map(int, input().split())
# 0์ผ๋ก ๋ถ๋ชจ ๋ฐฐ์ด ์ด๊ธฐํ
parent = [0 for _ in range(node + 1)]
# ๋ถ๋ชจ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ
for i in range(1, node + 1):
parent[i] = i
# union ์ฐ์ฐ
for i in range(edge):
a, b = map(int, input().split())
union_parent(parent, a, b)
# ๊ฐ ์์๊ฐ ์ํด์๋ ์งํฉ ์ถ๋ ฅ
for i in range(1, node + 1):
print(find_parent(parent, i), end=' ')
print()
# ๋ถ๋ชจ ํ
์ด๋ธ ์ถ๋ ฅ
for i in range(1, node + 1):
print(parent[i], end=' ')
์ต์ ํ
๊ฒฝ๋ก ์์ถ (Path compression)
# ๊ฒฝ๋ก ์์ถ -> ๋ถ๋ชจ๊ฐ ์ฌ๊ท์ ์ผ๋ก ๊ฐฑ์
def find_parent_compression(parent, node):
if parent[node] != node:
parent[node] = find_parent_compression(parent, parent[node])
return parent[node]
Rank ์ด์ฉ (Union by Rank)
# rank: ๊ฐ ๋
ธ๋์ rank๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ
rank = [0 for _ in range(N + 1)]
# def union_parent_rank(x, y):
x = find_parent(x)
y = find_parent(y)
if x == y:
return
# ๋ญํฌ๊ฐ ๋ฎ์ ์งํฉ์ ๋์ ์งํฉ์ผ๋ก ๋ณํฉํด์ค๋ค
if rank[x] > rank[y]:
parent[y] = x
else:
parent[x] = y
# ๋ญํฌ๊ฐ ๋์ผํ ๊ฒฝ์ฐ
if rank[x] == rank[y]:
rank[y] += 1
์ฝ๋ ์์
def find_parent(x):
if parent[x] != x:
parent[x] = find_parent(parent[x])
return parent[x]
def union_parent(x, y):
x = find_parent(x)
y = find_parent(y)
if x == y:
return
if rank[x] > rank[y]:
parent[y] = x
else:
parent[x] = y
if rank[x] == rank[y]:
rank[y] += 1
# ๋
ธ๋์ ๊ฐ์ (union ์ฐ์ฐ) ๊ฐ์
node, edge = map(int, input().split())
# 0์ผ๋ก ๋ถ๋ชจ ๋ฐฐ์ด ์ด๊ธฐํ
parent = [0 for _ in range(node + 1)]
# 1๋ก ๋ญํฌ ์ด๊ธฐํ
rank = [1 for _ in range(node + 1)]
# ๋ถ๋ชจ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ
for i in range(1, node + 1):
parent[i] = i
# union ์ฐ์ฐ
for i in range(edge):
a, b = map(int, input().split())
union_parent(a, b)
# ๊ฐ ์์๊ฐ ์ํด์๋ ์งํฉ ์ถ๋ ฅ
for i in range(1, node + 1):
print(find_parent(i), end=' ')
print()
# ๋ถ๋ชจ ํ
์ด๋ธ ์ถ๋ ฅ
for i in range(1, node + 1):
print(parent[i], end=' ')
Weighted Union Find
โ parent ๋ฐฐ์ด์ด ์์์ผ ๊ฒฝ์ฐ ๋ถ๋ชจ๋ ธ๋๋ก์ ์์์ ์ ๋๊ฐ์ด size(rank)๊ฐ ๋๊ณ , ์์์ผ ๊ฒฝ์ฐ ๋ถ๋ชจ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํจ๋ค
parent = [-1 for _ in range(N + 1)]
def find_parent(x):
if parent[x] < 0:
return x
p = find(parent[x])
parent[x] = p
return p
def union_parent(x, y):
x = find_parent(x)
y = find_parent(y)
if x == y:
return
if parent[x] < parent[y]:
parent[x] += parent[y]
parent[y] = x
else:
parent[y] += parent[x]
parent[x] = y
'โญ Personal_Study > Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Segment Tree (0) | 2022.12.03 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] ๋ค์ต์คํธ๋ผ (Dijkstra) (0) | 2022.10.01 |
[์๊ณ ๋ฆฌ์ฆ] ์ต์ ์ ์ฅ ํธ๋ฆฌ (MST) (1) | 2022.09.29 |
๋๊ธ