๊ด€๋ฆฌ ๋ฉ”๋‰ด

DOing

[์•Œ๊ณ ๋ฆฌ์ฆ˜] Disjoint Sets(์„œ๋กœ์†Œ ์ง‘ํ•ฉ) ๋ณธ๋ฌธ

์•Œ๊ณ ๋ฆฌ์ฆ˜

[์•Œ๊ณ ๋ฆฌ์ฆ˜] Disjoint Sets(์„œ๋กœ์†Œ ์ง‘ํ•ฉ)

mangdo 2021. 5. 31. 15:46

๐Ÿ’ก Disjoint Sets(์„œ๋กœ์†Œ ์ง‘ํ•ฉ)?

์„œ๋กœ์†Œ ๊ด€๊ณ„์ด๋‹ค / ์„œ๋กœ์†Œ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋‹ค

  ์„œ๋กœ์†Œ ์ง‘ํ•ฉ์ด๋ž€, ๊ณตํ†ต ์›์†Œ๊ฐ€ ์—†๋Š” ๋‘์ง‘ํ•ฉ์„ ์˜๋ฏธํ•œ๋‹ค. ์™ผ์ชฝ ๊ทธ๋ฆผ์—์„œ ์ง‘ํ•ฉ A์™€ B๋Š” ์„œ๋กœ์†Œ ๊ด€๊ณ„์ด๊ณ , ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์—์„œ  ์ง‘ํ•ฉ A์™€ B๋Š” ์„œ๋กœ์†Œ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋‹ค.

 ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์„œ๋กœ์†Œ ๋ถ€๋ถ„ ์ง‘ํ•ฉ๋“ค๋กœ ๋‚˜๋ˆ„์–ด์ง„ ์›์†Œ๋“ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.  ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” union-find ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค. ์‚ฌ์šฉ๋˜๋Š” ์—ฐ์‚ฐ์˜ ์ด๋ฆ„ ์ž์ฒด๊ฐ€ union๊ณผ find์ด๊ธฐ๋„ ํ•˜๊ณ , ๋‘ ์ง‘ํ•ฉ์ด ์„œ๋กœ์†Œ ๊ด€๊ณ„์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์€ ๊ฐ ์ง‘ํ•ฉ์ด ์–ด๋–ค ์›์†Œ๋ฅผ ๊ณตํ†ต์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง๊ณผ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๐Ÿ’ก Disjoint Sets ๋™์ž‘ ๊ณผ์ •

 Disjoint Sets ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ง‘ํ•ฉ์„ ํ‘œํ˜„ํ•œ๋‹ค. ํŠธ๋ฆฌ๋กœ ๋ถ€๋ถ„์ง‘ํ•ฉ์„ ํ‘œํ˜„ํ•˜๊ณ  find๋ฅผ ํ†ตํ•ด ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ณ  union์œผ๋กœ ํŠธ๋ฆฌ๋ฅผ ํ•ฉ์นœ๋‹ค. ์„œ๋กœ์†Œ ์ง‘ํ•ฉ ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. union(ํ•ฉ์ง‘ํ•ฉ)์—ฐ์‚ฐ์„ ํ™•์ธํ•˜์—ฌ, ์„œ๋กœ ์—ฐ๊ฒฐ๋œ ๋‘ ๋…ธ๋“œ A, B๋ฅผ ํ™•์ธํ•œ๋‹ค.

    1) A์™€ B์˜ ๋ฃจํŠธ๋…ธ๋“œ A'์™€ B'๋ฅผ ๊ฐ๊ฐ ์ฐพ๋Š”๋‹ค.

    2) A'๋ฅผ B'์˜ ๋ถ€๋ชจ๋…ธ๋“œ๋กœ ์„ค์ •ํ•œ๋‹ค.(=B'๊ฐ€ A'๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•œ๋‹ค.)

      * ๋ณดํ†ต A'์™€ B'์ค‘์—์„œ ๋” ๋ฒˆํ˜ธ ์ž‘์€ ์›์†Œ๊ฐ€ ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ๋˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค.

2. ๋ชจ๋“  union(ํ•ฉ์ง‘ํ•ฉ) ์—ฐ์‚ฐ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ๊นŒ์ง€ 1๋ฒˆ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

 

์˜ˆ์‹œ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ union์—ฐ์‚ฐ์„ ์ฃผ์–ด์กŒ์„ ๋•Œ ๋™์ž‘๊ณผ์ •์„ ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

union(1, 4) union(2, 3) union(2, 4) union(5, 6)

 

[ ์ดˆ๊ธฐ ๋‹จ๊ณ„ ]

 ์ดˆ๊ธฐ ๋‹จ๊ณ„์—์„œ๋Š” ์ž๊ธฐ์ž์‹ ์„ ๋ฃจํŠธ๋…ธ๋“œ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 ์œ ์˜ํ•  ์ ์€ ์—ฌ๊ธฐ์„œ์˜ ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์€ ๋ถ€๋ชจ์— ๋Œ€ํ•œ ์ •๋ณด๋งŒ์„ ๋‹ด๊ณ  ์žˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ํŠน์ • ๋…ธ๋“œ์˜ ๋ฃจํŠธ๋ฅผ ํ™•์ธํ•˜๊ณ ์ž ํ• ๋•Œ๋Š” ์žฌ๊ท€์ ์œผ๋กœ ๋ถ€๋ชจ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€์„œ ์ตœ์ข…์ ์ธ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์•„์•ผํ•œ๋‹ค

[ step1 ]

1) 1์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋Š” 1์ด๊ณ , 4์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 4์ด๋‹ค.

2) ๋” ์ž‘์€ ๋ฃจํŠธ๋…ธ๋“œ์ธ 1์„ ๋ฃจํŠธ๋…ธ๋“œ 4์˜ ๋ถ€๋ชจ๋กœ ์„ค์ •ํ•œ๋‹ค.

 

[ step2 ]

1) 2์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 2์ด๊ณ , 3์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 3์ด๋‹ค.

2) ๋” ์ž‘์€ ๋ฃจํŠธ๋…ธํŠธ์ธ 2์„ ๋ฃจํŠธ๋…ธ๋“œ 3์˜ ๋ถ€๋ชจ๋กœ ์„ค์ •ํ•œ๋‹ค.

 

[ step3 ]

1) 2์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 2์ด๊ณ , 4์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 1์ด๋‹ค.

2) ๋” ์ž‘์€ ๋ฃจํŠธ๋…ธ๋“œ์ธ 1์„ ๋ฃจํŠธ๋…ธ๋“œ 2์˜ ๋ถ€๋ชจ๋กœ ์„ค์ •ํ•œ๋‹ค.

 

[ step4 ]

1) 5์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 5์ด๊ณ , 6์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 6์ด๋‹ค.

2) ๋” ์ž‘์€ ๋ฃจํŠธ๋…ธ๋“œ์ธ 5๋ฅผ ๋ฃจํŠธ๋…ธ๋“œ 6์˜ ๋ถ€๋ชจ๋กœ ์„ค์ •ํ•œ๋‹ค.

 

๐Ÿ’ก Disjoint Sets ๊ตฌํ˜„

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

# ๋‘ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ํ•ฉ์น˜๋Š” union์—ฐ์‚ฐ
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 = [i for i in range(v+1)] # ์ดˆ๊ธฐ ์ƒํƒœ์—์„œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” ์ž๊ธฐ์ž์‹ 

# 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 

 

๐Ÿ’ก ๊ฒฝ๋กœ ์••์ถ• ๊ธฐ๋ฒ•

์œ„์˜ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„์‹œ์— ๋‹ต์„ ๊ตฌํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, findํ•จ์ˆ˜๊ฐ€ ๋น„ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค๋Š” ๋ฌธ์ œ์ ์ด ์žˆ๋‹ค. ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•ด์„œ ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์„ ๊ณ„์†ํ•ด์„œ ํ™•์ธํ•˜๋ฉฐ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ตœ์•…์˜ ๊ฒฝ์šฐ findํ•จ์ˆ˜๊ฐ€ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋‹ค ํ™•์ธํ•˜๋Š” ํ„ฐ๋ผ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(V)์ด๋‹ค. 

 ์ด๋Ÿฌํ•œ findํ•จ์ˆ˜๋ฅผ ๊ฒฝ๋กœ ์••์ถ• ๊ธฐ๋ฒ•(Path Compression)์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์— ๋ฃจํŠธ๋…ธ๋“œ๋ฅผ ๋ฐ”๋กœ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒฝ๋กœ ์••์ถ• ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฃจํŠธ๋…ธ๋“œ์— ๋”์šฑ ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์„  ์˜ˆ์‹œ๋“ค๊ณผ ๋™์ผํ•œ ์ƒํ™ฉ์— ๋Œ€ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •์ด ๋œ๋‹ค.

์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ ๋™์ผํ•˜๊ณ  find_parent()๋งŒ ์ˆ˜์ •๋œ๋‹ค.

# ํŠน์ • ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ์ฐพ๊ธฐ์œ„ํ•ด์„œ ๋ฃจํŠธ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” find์—ฐ์‚ฐ
def find_parent(parent, x):
    
    # ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœ
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x]) # ๋ถ€๋ชจ๋ฅผ ๋ฃจํŠธ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝ
    
    return parent[x]
์ž…๋ ฅ ์ถœ๋ ฅ
6 4
1 4
2 3
2 4
5 6
๊ฐ ์›์†Œ์˜ ๋ฃจํŠธ๋…ธ๋“œ: 1 1 1 1 5 5 
๋ถ€๋ชจํ…Œ์ด๋ธ”: 1 1 1 1 5 5 

 

๐Ÿ’ก ์‚ฌ์ดํด ํŒ๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜

Disjoint Sets๋Š” ๋‹ค์–‘ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ ๋‚ด์—์„œ์˜ ์‚ฌ์ดํด์„ ํŒ๋ณ„ํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๋ฐฉํ–ฅ๊ทธ๋ž˜ํ”„์—์„œ์˜ ์‚ฌ์ดํด ์—ฌ๋ถ€๋Š” DFS๋ฅผ ์ด์šฉํ•ด ํŒ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[ ๋™์ž‘ ๊ณผ์ • ]

1. ๊ฐ ๊ฐ„์„ ์„ ํ™•์ธํ•˜๋ฉฐ ๋‘ ๋…ธ๋“œ์˜ ๋ฃจํŠธ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•œ๋‹ค.

2. ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋ฉด ๋‘ ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ union์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

3. ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๊ฐ™๋‹ค๋ฉด ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋‹ค.

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

   ๋งŒ์•ฝ ๋ชจ๋“  ๊ฐ„์„ ์ด ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํ•ด๋‹น ๊ทธ๋ž˜ํ”„์—์„œ๋Š” ์‚ฌ์ดํด์ด ์—†๋‹ค๋ผ๊ณ  ํŒ๋‹จ๋  ์ˆ˜ ์žˆ๋‹ค.

 

[ step0 ]

[ step 1 ]

1. 1์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 1, 2์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 2์ด๋‹ค.

2. ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋…ธ๋“œ์— ๋Œ€ํ•ด union์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

[ step 2 ]

1. 1์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 1์ด๊ณ  3์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 3์ด๋‹ค.

2. ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋…ธ๋“œ์— ๋Œ€ํ•ด union์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

[ step 3 ]

1. 2์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 1์ด๊ณ  3์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” 1์ด๋‹ค.

2. ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๊ฐ™๋‹ค. ๋‘ ๋…ธ๋“œ๊ฐ€ ์ด๋ฏธ ๊ฐ™์€ ๋…ธ๋“œ์— ์†ํ•ด ์žˆ๋‹ค๋Š” ๋œป์ด๊ณ  ํ•ด๋‹น ๊ทธ๋ž˜ํ”„์— ์‚ฌ์ดํด์ด ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

 

๐Ÿ’ก ์‚ฌ์ดํด ํŒ๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„

# ํŠน์ • ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ์ฐพ๊ธฐ์œ„ํ•ด์„œ ๋ฃจํŠธ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” find์—ฐ์‚ฐ
def find_parent(parent, x):
    
    # ๋ฃจํŠธ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœ
    if parent[x] != x:
    	parent[x] = find_parent(parent, parent[x]) # ๋ถ€๋ชจ๋ฅผ ๋ฃจํŠธ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝ
    
    return parent[x]

# ๋‘ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ํ•ฉ์น˜๋Š” union์—ฐ์‚ฐ
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 = [i for i in range(v+1)] # ์ดˆ๊ธฐ ์ƒํƒœ์—์„œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋ฃจํŠธ๋…ธ๋“œ๋Š” ์ž๊ธฐ์ž์‹ 

# ์‚ฌ์ดํด ๋ฐœ์ƒ ์—ฌ๋ถ€
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)
    union_parent(parent, a, b)

# ์‚ฌ์ดํด ๋ฐœ์ƒ์—ฌ๋ถ€ ์ถœ๋ ฅ
if cycle:
    print("์‚ฌ์ดํด์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค")
else:
    print("์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค")

 

์ž…๋ ฅ ์ถœ๋ ฅ
3 3
1 2
1 3
2 3
์‚ฌ์ดํด์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค