๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm/์•Œ๊ณ ๋ฆฌ์ฆ˜

[Algorithm] ํด๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Kruskal Algorithm)

1. ์‹ ์žฅํŠธ๋ฆฌ๋ž€?

  • ๊ทธ๋ž˜ํ”„์—์„œ 1) ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํฌํ•จํ•˜๋ฉด์„œ 2) ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„ ๊ทธ๋ž˜ํ”„๋ฅผ ์˜๋ฏธ
  • ์ด๋Š” ํŠธ๋ฆฌ์˜ ์กฐ๊ฑด์ด๊ธฐ๋„ ํ•จ

2 . ์ตœ์†Œ์‹ ์žฅํŠธ๋ฆฌ

  • ์ตœ์†Œ์˜ ๋น„์šฉ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋Š” ์‹ ์žฅ ํŠธ๋ฆฌ๋ฅผ ์ฐพ์•„์•ผ ํ•  ๋•Œ
  • N๊ฐœ์˜ ๋„์‹œ๊ฐ€ ์กด์žฌํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋‘ ๋„์‹œ ์‚ฌ์ด์— ๋„๋กœ๋ฅผ ๋†“์•„ ์ „์ฒด ๋„์‹œ๊ฐ€ ์„œ๋กœ ์—ฐ๊ฒฐ ๋  ์ˆ˜ ์žˆ๊ฒŒ ๋„๋กœ๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒฝ์šฐ

3. ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ถ„๋ฅ˜
  • ๋™์ž‘ ๊ณผ์ •
    • ๊ฐ„์„  ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์šฉ์— ๋”ฐ๋ผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ
    • ๊ฐ„์„ ์„ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๋ฉฐ ํ˜„์žฌ์˜ ๊ฐ„์„ ์ด ์‚ฌ์ดํด์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š”์ง€ ํ™•์ธ
      ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ → ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ์— ํฌํ•จ
      ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ → ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ์— ํฌํ•จ X
    1. ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•˜์—ฌ 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 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)

4. ์„ฑ๋Šฅ๋ถ„์„

  • ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๊ฐ€ N๊ฐœ์ผ ๋•Œ, O(NlogN)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง
  • ๊ฐ€์žฅ ๋งŽ์€ ์‹œ๊ฐ„ ๊ฑธ๋ฆฌ๋Š” ๊ณณ: ๊ฐ„์„ ์ •๋ ฌ์ˆ˜ํ–‰ ๋ถ€๋ถ„
    • sort()๋ฅผ ์ด์šฉํ•ด N๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(NlogN)

5. ์ฐธ๊ณ ์ž๋ฃŒ

https://www.youtube.com/watch?v=Gj7s-Nrt1xE