๐Ÿ“š ๋ณต์Šต

DFS/BFS์™€ ์ตœ๋‹จ๊ฒฝ๋กœ๋Š” ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ•œ ์œ ํ˜• ์ด๋ฉฐ ์ด์™ธ์—๋„ ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ต‰์žฅํžˆ ๋‹ค์–‘ํ•œ๋ฐ, ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ์—์„œ ์ถœ์ œ ๋น„์ค‘์ด ๋‚ฎ์ง€๋งŒ ๊ผญ ์•Œ์•„์•ผ ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. 10์žฅ์—์„œ ๋‹ค๋ฃฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•ž์„œ ๋ฐฐ์šด ๋‚ด์šฉ์— ๊ธฐ๋ฐ˜ํ•œ๋‹ค.

  • ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Kruskal Algorithms): ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ•œ ์œ ํ˜•
  • ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Topology Algorithms): ํ ์ž๋ฃŒ๊ตฌ์กฐ or ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„

๐Ÿ“Œ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋ฅผ ์ ‘ํ–ˆ์„ ๋•Œ ์•Œ์•„๋‘์–ด์•ผ ํ•  ์ 

  • โ€˜์„œ๋กœ ๋‹ค๋ฅธ ๊ฐœ์ฒด(ํ˜น์€ ๊ฐ์ฒด)๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹คโ€™๋Š” ์ด์•ผ๊ธฐ๋Š” ๊ฐ€์žฅ ๋จผ์ € ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋– ์˜ฌ๋ ค์•ผ ํ•œ๋‹ค.
    • ์˜ˆ๋ฅผ๋“ค์–ด โ€˜์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋„์‹œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹คโ€™์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด ๋“ฑ์žฅํ•˜๋ฉด ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์˜์‹ฌํ•ด๋ณด์ž.

๊ทธ๋ž˜ํ”„ ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘์—์„œ ํŠธ๋ฆฌ(Tree) ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋‹ค์–‘ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๊ผญ ๊ธฐ์–ต.

  • ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋ถ€๋ชจ -> ์ž์‹์œผ๋กœ ๋‚ด๋ ค์˜ค๋Š” ๊ณ„์ธต์ ์ธ ๋ชจ๋ธ์ด๋‹ค.
  • ํŠธ๋ฆฌ๋Š” ์ˆ˜ํ•™์—์„œ๋Š” ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„๋กœ ๊ฐ„์ฃผํ•˜์ง€๋งŒ, ์ปดํ“จํ„ฐ๊ณตํ•™ ๋ถ„์•ผ์—์„œ๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.

๊ทธ๋ž˜ํ”„ํŠธ๋ฆฌ

์•ž์„œ ๊ทธ๋ž˜ํ”„์˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์—๋Š” 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ–ˆ๋‹ค. ๋‘ ๋ฐฉ์‹์€ ๋ฉ”๋ชจ๋ฆฌ์™€ ์†๋„ ์ธก๋ฉด์—์„œ ๊ตฌ๋ณ„๋œ๋‹ค.

  • ์ธ์ ‘ ํ–‰๋ ฌ(Adjacency Matrix): 2์ฐจ์› ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹
    • ๊ฐ„์„  ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด O(Vยฒ)๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ํ•„์š”
    • ํŠน์ • ๋…ธ๋“œ A์—์„œ ๋‹ค๋ฅธ ํŠน์ • ๋…ธ๋“œ B๋กœ ์ด์–ด์ง„ ๊ฐ„์„ ์˜ ๋น„์šฉ์„ O(1) ์‹œ๊ฐ„์œผ๋กœ ์ฆ‰์‹œ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
    • ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ธ์ ‘ ํ–‰๋ ฌ์„ ์ด์šฉ
      • ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ์ตœ์†Œ ๋น„์šฉ์„ Vยฒ ํฌ๊ธฐ์˜ 2์ฐจ์› ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•œ ๋’ค์—, ํ•ด๋‹น ๋น„์šฉ์„ ๊ฐฑ์‹ ํ•ด์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐ
  • ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ(Adjacency List): ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹
    • ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๋งŒํผ์ธ O(E)๋งŒํผ๋งŒ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ํ•„์š”
    • ํŠน์ • ๋…ธ๋“œ A์—์„œ ๋‹ค๋ฅธ ํŠน์ • ๋…ธ๋“œ B๋กœ ์ด์–ด์ง„ ๊ฐ„์„ ์˜ ๋น„์šฉ์„ ์•Œ๋ ค๋ฉด O(V)๋งŒํผ์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋œ๋‹ค.
    • ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•˜๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉ
      • V๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ

๐Ÿ“Œ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ์‹œ ์•Œ์•„๋‘์–ด์•ผ ํ•  ์ 

  • ๋ฉ”๋ชจ๋ฆฌ์™€ ์‹œ๊ฐ„์„ ์—ผ๋‘์— ๋‘๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•ด์„œ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„์•ผํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๋•Œ, ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ ์€ ๊ฒฝ์šฐ์—๋Š” ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„, ๋…ธ๋“œ์™€ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์œ ๋ฆฌํ•˜๋‹ค.

๐Ÿ“š ์„œ๋กœ์†Œ ์ง‘ํ•ฉ (Disjoint Sets) ์•Œ๊ณ ๋ฆฌ์ฆ˜

์„œ๋กœ์†Œ ์ง‘ํ•ฉ (Disjoint Sets)๋ž€ ๊ณตํ†ต ์›์†Œ๊ฐ€ ์—†๋Š” ๋‘ ์ง‘ํ•ฉ์„ ์˜๋ฏธํ•œ๋‹ค.

์„œ๋กœ์†Œ์ง‘ํ•ฉ

  • ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ๋ž€ ์„œ๋กœ์†Œ ๋ถ€๋ถ„ ์ง‘ํ•ฉ๋“ค๋กœ ๋‚˜๋ˆ„์–ด์ง„ ์›์†Œ๋“ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋‘ ์ข…๋ฅ˜์˜ ์—ฐ์‚ฐ์„ ์ง€์›ํ•œ๋‹ค.
    • ํ•ฉ์ง‘ํ•ฉ(Union): ๋‘ ๊ฐœ์˜ ์›์†Œ๊ฐ€ ํฌํ•จ๋œ ์ง‘ํ•ฉ์„ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์œผ๋กœ ํ•ฉ์น˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค.
    • ์ฐพ๊ธฐ(Find): ํŠน์ •ํ•œ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์ด ์–ด๋–ค ์ง‘ํ•ฉ์ธ์ง€ ์•Œ๋ ค์ฃผ๋Š” ์—ฐ์‚ฐ์ด๋‹ค.
  • ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ํ•ฉ์น˜๊ธฐ ์ฐพ๊ธฐ(Union Find) ์ž๋ฃŒ๊ตฌ์กฐ ๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•œ๋‹ค.

์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ

  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•ฉ์น˜๊ธฐ ์—ฐ์‚ฐ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ์˜ ๋™์ž‘ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1. ํ•ฉ์นฉํ•ฉ(Union) ์—ฐ์‚ฐ์„ ํ™•์ธํ•˜์—ฌ, ์„œ๋กœ ์—ฐ๊ฒฐ๋œ ๋‘ ๋…ธ๋“œ A, B๋ฅผ ํ™•์ธํ•œ๋‹ค.

      1) A์™€ B์˜ ๋ฃจํŠธ ๋…ธ๋“œ Aโ€™, Bโ€™๋ฅผ ๊ฐ๊ฐ ์ฐพ๋Š”๋‹ค.
      2) Aโ€™๋ฅผ Bโ€™์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ ์„ค์ •ํ•œ๋‹ค.

    2. ๋ชจ๋“  ํ•ฉ์ง‘ํ•ฉ(Union) ์—ฐ์‚ฐ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ๊นŒ์ง€ 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=' ')
#์ž…๋ ฅ ์˜ˆ์‹œ
6 4
1 4
2 3
2 4
5 6

#์ถœ๋ ฅ ์˜ˆ์‹œ
๊ฐ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ: 1 1 1 1 5 5
๋ถ€๋ชจ ํ…Œ์ด๋ธ”: 1 1 2 1 5 5

์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ: ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์˜ ๋ฌธ์ œ์ 

  • ํ•ฉ์ง‘ํ•ฉ(Union) ์—ฐ์‚ฐ์ด ํŽธํ–ฅ๋˜๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ ์ฐพ๊ธฐ(Find) ํ•จ์ˆ˜๊ฐ€ ๋น„ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•จ
  • ์ตœ์•…์˜ ๊ฒฝ์šฐ์—๋Š” ์ฐพ๊ธฐ(Find) ํ•จ์ˆ˜๊ฐ€ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋‹ค ํ™•์ธํ•˜๊ฒŒ ๋˜์–ด ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(V)
    • ๋‹ค์Œ๊ณผ ๊ฐ™์ด {1, 2, 3, 4, 5]์˜ ์ด 5๊ฐœ์˜ ์›์†Œ๊ฐ€ ์กด์žฌํ•˜๋Š” ์ƒํ™ฉ์„ ํ™•์ธํ–ˆ์„ ๊ฒฝ์šฐ
    • ์ˆ˜ํ–‰๋œ ์—ฐ์‚ฐ๋“ค: Union(4,5), Union(3,4), Union(2,3), Union(1,2)

์„œ๋กœ์†Œ๋™์ž‘๋ฌธ์ œ์ 

์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ ๊ตฌ์กฐ: ๊ฒฝ๋กœ ์••์ถ•

  • ์ฐพ๊ธฐ(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) ํ•จ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์ด ๊ฐฑ์‹ 
  • ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์— ๋น„ํ•˜์—ฌ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ ๊ฐœ์„ ๋จ

์„œ๋กœ์†Œ๋™์ž‘๋ฌธ์ œ์ 

# ํŠน์ • ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ์ฐพ๊ธฐ
def find_parent(parent, x):
    # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ
    if parent[x] != x:
        return 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, 1), end=' ')

print()

# ๋ถ€๋ชจ ํ…Œ์ด๋ธ” ๋‚ด์šฉ ์ถœ๋ ฅํ•˜๊ธฐ
print('๋ถ€๋ชจ ํ…Œ์ด๋ธ”: ', end='')
for i in range(1, v + 1):
    print(parent[i], end=' ')
#์ž…๋ ฅ ์˜ˆ์‹œ
6 4
1 4
2 3
2 4
5 6

#์ถœ๋ ฅ ์˜ˆ์‹œ
๊ฐ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ: 1 1 1 1 5 5
๋ถ€๋ชจ ํ…Œ์ด๋ธ”: 1 1 1 1 5 5 

์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„

  • ๊ฒฝ๋กœ ์••์ถ• ๋ฐฉ๋ฒ•๋งŒ์„ ์‚ฌ์šฉํ•˜๋ฉฐ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๊ฐ€ v, ์ตœ๋Œ€ v-1๊ฐœ์˜ union ์—ฐ์‚ฐ๊ณผ m๊ฐœ์˜ find ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๋ฉด
  • ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” $O(V + M(1+log_{2-M/V}V))$์ด๋‹ค.
  • ๋” ์งง์€ ๋ฐฉ๋ฒ•๋„ ์กด์žฌํ•˜์ง€๋งŒ ์ฝ”ํ…Œ ์ˆ˜์ค€์—์„œ ๊ฒฝ๋กœ ์••์ถ•๋งŒ ์ ์šฉํ•ด๋„ ์ถฉ๋ถ„ํ•˜๋ฉฐ ๊ฐœ๋… ๋ฐ ๊ตฌํ˜„ ๊ฐ„๋‹จํ•˜๋‹ค.

์„œ๋กœ์†Œ ์ง‘ํ•ฉ์„ ํ™œ์šฉํ•œ ์‚ฌ์ดํด ํŒ๋ณ„

  • ์„œ๋กœ์†Œ ์ง‘ํ•ฉ์€ ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ ๋‚ด์—์„œ์˜ ์‚ฌ์ดํด์„ ํŒ๋ณ„ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ฐธ๊ณ ๋กœ ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—์„œ์˜ ์‚ฌ์ดํด ์—ฌ๋ถ€๋Š” DFS๋ฅผ ์ด์šฉํ•˜์—ฌ ํŒ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.(ํ•ด๋‹น ๋‚ด์šฉ์€ ์ฑ…์—์„œ ๋‹ค๋ฃจ์ง€ ์•Š๋Š”๋‹ค)
  • ์‚ฌ์ดํด ํŒ๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1. ๊ฐ ๊ฐ„์„ ์„ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๋ฉฐ ๋‘ ๋…ธ๋“œ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•œ๋‹ค.

      1) ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋ฉด ๋‘ ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ ํ•ฉ์ง‘ํ•ฉ(Union) ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
      2) ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๊ฐ™๋‹ค๋ฉด ์‚ฌ์ดํด(Cycle)์ด ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋‹ค.

    2. ๊ทธ๋ž˜ํ”„์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•˜์—ฌ 1๋ฒˆ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

์„œ๋กœ์†Œ ์ง‘ํ•ฉ์„ ํ™œ์šฉํ•œ ์‚ฌ์ดํด ํŒ๋ณ„: ๋™์ž‘ ๊ณผ์ • ์‚ดํŽด๋ณด๊ธฐ

์„œ๋กœ์†Œ์‚ฌ์ดํด

์„œ๋กœ์†Œ์‚ฌ์ดํด

์„œ๋กœ์†Œ์‚ฌ์ดํด

์„œ๋กœ์†Œ์‚ฌ์ดํด

# ํŠน์ • ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ์ฐพ๊ธฐ
def find_parent(parent, x):
    # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ
    if parent[x] != x:
        return 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("์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
#์ž…๋ ฅ ์˜ˆ์‹œ
3 3
1 2
1 3
2 3

#์ถœ๋ ฅ ์˜ˆ์‹œ
์‚ฌ์ดํด์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“š ์‹ ์žฅํŠธ๋ฆฌ (Spanning Tree)

  • ๊ทธ๋ž˜ํ”„๊ฐ€ ์žˆ์„ ๋•Œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํฌํ•จํ•˜๋ฉด์„œ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„ ๊ทธ๋ž˜ํ”„๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
    • ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์—ฐ๊ฒฐ๋˜๋ฉด์„œ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์กฐ๊ฑด์€ ํŠธ๋ฆฌ์˜ ์„ฑ๋ฆฝ ์กฐ๊ฑด์ด๊ธฐ๋„ ํ•˜๋‹ค.

์‹ ์žฅํŠธ๋ฆฌ

  • ์‹ ์žฅ ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„์€ 1๋ฒˆ ๋…ธ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉฐ, ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค.

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

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

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

  • ๋Œ€ํ‘œ์ ์ธ ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ถ„๋ฅ˜
  • ํŠธ๋ฆฌ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋ฏ€๋กœ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๋Š” โ€˜๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜-1โ€™๊ณผ ๊ฐ™๋‹ค.
  • ๊ตฌ์ฒด์ ์ธ ๋™์ž‘ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1. ๊ฐ„์„  ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์šฉ์— ๋”ฐ๋ผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ
    2. ๊ฐ„์„ ์„ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๋ฉฐ ํ˜„์žฌ์˜ ๊ฐ„์„ ์ด ์‚ฌ์ดํด์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

      1) ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ์— ํฌํ•จํ•œ๋‹ค.
      2) ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ์— ํฌํ•จ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

    3. ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•˜์—ฌ 2๋ฒˆ์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜: ๋™์ž‘ ๊ณผ์ •

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

ํฌ๋ฃจ์Šค์นผ

# ํŠน์ • ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ์ฐพ๊ธฐ
def find_parent(x):
    # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ
    if parent[x] != x:
        parent[x] = find_parent(parent[x])
    return parent[x]

# ๋‘ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ํ•ฉ์น˜๊ธฐ
def union_parent(a, b):
    a = find_parent(a)
    b = find_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(a) != find_parent(b):
        union_parent(a, b)
        result += cost

print(result)
#์ž…๋ ฅ ์˜ˆ์‹œ
7 9
1 2 29
1 5 75
2 3 35
2 6 34
3 4 7
4 6 23
4 7 13
5 6 53
6 7 25

#์ถœ๋ ฅ ์˜ˆ์‹œ
159

ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜: ์„ฑ๋Šฅ ๋ถ„์„

  • ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜๊ฐ€ E๊ฐœ์ผ ๋•Œ, O(ElogE)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ์™œ๋ƒํ•˜๋ฉด ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๊ฐ€์žฅ ๋งŽ์€ ์‹œ๊ฐ„์„ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„์„ ์˜ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.
    • ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด E๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(ElogE)

๐Ÿ“š ์œ„์ƒ ์ •๋ ฌ (Topology Sort)

  • ์‚ฌ์ดํด์ด ์—†๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ โ€˜๋ฐฉํ–ฅ์„ฑ์— ๊ฑฐ์Šค๋ฅด์ง€ ์•Š๋„๋ก ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•˜๋Š” ๊ฒƒโ€™์„ ์˜๋ฏธ
  • ์˜ˆ์‹œ) ์„ ์ˆ˜๊ณผ๋ชฉ์„ ๊ณ ๋ คํ•œ ํ•™์Šต ์ˆœ์„œ ์„ค์ •

์œ„์ƒ์ •๋ ฌ

  • ์œ„ ์„ธ ๊ณผ๋ชฉ์„ ๋ชจ๋‘ ๋“ฃ๊ธฐ ์œ„ํ•œ ์ ์ ˆํ•œ ํ•™์Šต ์ˆœ์„œ๋Š”?
    • ์ž๋ฃŒ๊ตฌ์กฐ -> ์•Œ๊ณ ๋ฆฌ์ฆ˜ -> ๊ณ ๊ธ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (O)
    • ์ž๋ฃŒ๊ตฌ์กฐ -> ๊ณ ๊ธ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ -> ์•Œ๊ณ ๋ฆฌ์ฆ˜ (x)

์ง„์ž…์ฐจ์ˆ˜์™€ ์ง„์ถœ์ฐจ์ˆ˜

  • ์ง„์ž…์ฐจ์ˆ˜(Indegree): ํŠน์ •ํ•œ ๋…ธ๋“œ๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜
  • ์ง„์ถœ์ฐจ์ˆ˜(Outdegree): ํŠน์ •ํ•œ ๋…ธ๋“œ์—์„œ ๋‚˜๊ฐ€๋Š” ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜

์ง„์ž…์ฐจ์ˆ˜ ์ง„์ถœ์ฐจ์ˆ˜

์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ํ๋ฅผ ์ด์šฉํ•˜๋Š” ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋™์ž‘ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. (DFS๋กœ๋„ ๊ฐ€๋Šฅ)
    1. ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ธ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ์— ๋„ฃ๋Š”๋‹ค.
    2. ํ๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ๋‹ค์Œ์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
      1). ํ์—์„œ ์›์†Œ๋ฅผ ๊บผ๋‚ด ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ๋‚˜๊ฐ€๋Š” ๊ฐ„์„ ์„ ๊ทธ๋ž˜ํ”„์—์„œ ์ œ๊ฑฐํ•œ๋‹ค.
      2). ์ƒˆ๋กญ๊ฒŒ ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ด ๋œ ๋…ธ๋“œ๋ฅผ ํ์— ๋„ฃ๋Š”๋‹ค.

-> ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ์— ๋“ค์–ด์˜จ ์ˆœ์„œ๊ฐ€ ์œ„์ƒ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•œ ๊ฒฐ๊ณผ์™€ ๊ฐ™๋‹ค.

์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜: ๋™์ž‘ ๊ณผ์ •

  • ์œ„์ƒ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•  ๊ทธ๋ž˜ํ”„๋ฅผ ์ค€๋น„
    • ์ด๋•Œ ๊ทธ๋ž˜ํ”„๋Š” ์‚ฌ์ดํด์ด ์—†๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ (DAG)์—ฌ์•ผ ํ•œ๋‹ค.

์œ„์ƒ๋™์ž‘์˜ˆ์‹œ

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

  • ๋ณธ ์˜ˆ์ œ๋Š” ๋” ์ž‘์€ ๋ฒˆํ˜ธ์˜ ๋…ธ๋“œ๊ฐ€ ์šฐ์„ ์œผ๋กœ ํ์— ๋“ค์–ด๊ฐ€๊ฒŒ๋” ๊ฐ€์ •

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ์ •๋ ฌ๋™์ž‘

์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜: ํŠน์ง•

  • ์œ„์ƒ ์ •๋ ฌ์€ DAG์— ๋Œ€ํ•ด์„œ๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • DAG (Direct Acyclic Graph): ์ˆœํ™˜ํ•˜์ง€ ์•Š๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„
  • ์œ„์ƒ ์ •๋ ฌ์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ต์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํ•œ ๋‹จ๊ณ„์—์„œ ํ์— ์ƒˆ๋กญ๊ฒŒ ๋“ค์–ด๊ฐ€๋Š” ์›์†Œ๊ฐ€ 2๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ต์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ์›์†Œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ธฐ ์ „์— ํ๊ฐ€ ๋นˆ๋‹ค๋ฉด ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์‚ฌ์ดํด์— ํฌํ•จ๋œ ์›์†Œ ์ค‘์—์„œ ์–ด๋– ํ•œ ์›์†Œ๋„ ํ์— ๋“ค์–ด๊ฐ€์ง€ ๋ชปํ•œ๋‹ค.
  • ์Šคํƒ์„ ํ™œ์šฉํ•œ DFS๋ฅผ ์ด์šฉํ•ด ์œ„์ƒ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
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()
#์ž…๋ ฅ ์˜ˆ์‹œ
7 8
1 2
1 5
2 3
2 6
3 4
4 7
5 6
6 4

#์ถœ๋ ฅ ์˜ˆ์‹œ
1 2 5 3 6 4 7

์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜: ์„ฑ๋Šฅ ๋ถ„์„

  • ์œ„์ƒ ์ •๋ ฌ์„ ์œ„ํ•ด ์ฐจ๋ก€๋Œ€๋กœ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•˜๋ฉฐ ๊ฐ ๋…ธ๋“œ์—์„œ ๋‚˜๊ฐ€๋Š” ๊ฐ„์„ ์„ ์ฐจ๋ก€๋Œ€๋กœ ์ œ๊ฑฐํ•ด์•ผ ํ•จ
    • ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(V + E)

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ