πŸ—οΈ Algorithm/🟩 λ°±μ€€

🟩 [λ°±μ€€] [Python] [Gold4] 1976번_μ—¬ν–‰ κ°€μž

Dbswnstjd 2023. 4. 3. 16:13

문제

https://www.acmicpc.net/problem/1976

 

1976번: μ—¬ν–‰ κ°€μž

λ™ν˜μ΄λŠ” μΉœκ΅¬λ“€κ³Ό ν•¨κ»˜ 여행을 κ°€λ €κ³  ν•œλ‹€. ν•œκ΅­μ—λŠ” λ„μ‹œκ°€ N개 있고 μž„μ˜μ˜ 두 λ„μ‹œ 사이에 길이 μžˆμ„ μˆ˜λ„, 없을 μˆ˜λ„ μžˆλ‹€. λ™ν˜μ΄μ˜ μ—¬ν–‰ 일정이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 이 μ—¬ν–‰ κ²½λ‘œκ°€ κ°€λŠ₯ν•œ 것인

www.acmicpc.net

풀이

# λ°±μ€€ 1976번 문제 - μ—¬ν–‰ κ°€μž
import sys
sys.setrecursionlimit(10 ** 6)


# aκ°€ μ†ν•œ 집합과 bκ°€ μ†ν•œ 집합 ν•©μΉ˜κΈ°
def union(x, y):
    x = find(x)
    y = find(y)

    # a와 b의 λΆ€λͺ¨ λ…Έλ“œκ°€ κ°™μœΌλ©΄ λ™μΌν•œ μ§‘ν•©μ΄λ―€λ‘œ 리턴
    if x == y:
        return
    # λΆ€λͺ¨ λ…Έλ“œκ°€ λ‹€λ₯΄λ‹€λ©΄ 두 집합을 ν•©μΉœλ‹€.
    else:
        parent[y] = x


# λΆ€λͺ¨ λ…Έλ“œ μ°ΎκΈ°
def find(target):
    # 자기 μžμ‹ μ΄ λΆ€λͺ¨ λ…Έλ“œμ΄λ©΄ 자기 μžμ‹ μ„ 리턴
    if target == parent[target]:
        return target

    # λΆ€λͺ¨ λ…Έλ“œλ₯Ό μž¬κ·€ν•¨μˆ˜λ₯Ό 톡해 μ°ΎλŠ”λ‹€.
    parent[target] = find(parent[target])

    # μžμ‹ μ˜ λΆ€λͺ¨ λ…Έλ“œλ₯Ό 리턴
    return parent[target]


n = int(sys.stdin.readline())
m = int(sys.stdin.readline())
parent = [0] * (n + 1)

for k in range(1, n + 1):
    parent[k] = k

for i in range(1, n + 1):
    # κ·Έλž˜ν”„λ‘œ ν‘œν˜„
    graph = list(map(int, sys.stdin.readline().split()))

    # ν˜„μž¬ λ„μ‹œμ™€ μ—°κ²°λ˜μ–΄ μžˆλŠ” λ„μ‹œλ₯Ό 확인
    for j in range(1, len(graph) + 1):
        if graph[j - 1] == 1:
            union(i, j) # λ‘κ°œμ˜ λ„μ‹œλ₯Ό ν•©μΉ©ν•©μœΌλ‘œ ν‘œν˜„

# μ—¬ν–‰ κ³„νš
tour = list(map(int, sys.stdin.readline().split()))

# set() ν•¨μˆ˜λ₯Ό 톡해 합집합을 μ°ΎλŠ”λ‹€. 즉, λͺ¨λ“  λ„μ‹œκ°€ μ—°κ²°λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
res = set([find(i) for i in tour])

# res 의 길이가 1일 경우 λͺ¨λ“  λ„μ‹œκ°€ μ—°κ²°λ˜μ–΄ μžˆλ‹€λŠ” 것이닀.
if len(res) == 1:
    print('YES')
else:
    print('NO')

Union-Find μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λŠ” λ¬Έμ œμ΄λ‹€.

union-find μ•Œκ³ λ¦¬μ¦˜μ„ 잘 λͺ°λΌμ„œ ν•΄κ²°ν•˜μ§€ λͺ»ν•˜μ—¬μ„œ ꡬ글링을 톡해 문제λ₯Ό ν’€μ—ˆλ‹€.

아직 이해가 ν•„μš”ν•œ 것 κ°™λ‹€.

 

좜처: https://fre2-dom.tistory.com/207