[BOJ] #1976 ์—ฌํ–‰๊ฐ€์ž(Python)

    ๋ฐ˜์‘ํ˜•

    ๐ŸŒฑ ๋ฌธ์ œ

     

    1976๋ฒˆ: ์—ฌํ–‰ ๊ฐ€์ž

    ๋™ํ˜์ด๋Š” ์นœ๊ตฌ๋“ค๊ณผ ํ•จ๊ป˜ ์—ฌํ–‰์„ ๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค. ํ•œ๊ตญ์—๋Š” ๋„์‹œ๊ฐ€ N๊ฐœ ์žˆ๊ณ  ์ž„์˜์˜ ๋‘ ๋„์‹œ ์‚ฌ์ด์— ๊ธธ์ด ์žˆ์„ ์ˆ˜๋„, ์—†์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๋™ํ˜์ด์˜ ์—ฌํ–‰ ์ผ์ •์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ด ์—ฌํ–‰ ๊ฒฝ๋กœ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ธ

    www.acmicpc.net

     

    ๐ŸŒฑ ํ’€์ด

    0. ์ž…๋ ฅ ๋ฐ›๊ธฐ ๋ฐ ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™”

    n = int(input())
    m = int(input())
    graph = []
    parent = [i for i in range(n + 1)]
    
    for i in range(n):
        graph.append([idx + 1 for idx, i in enumerate(list(map(int, input().split()))) if i == 1])
    
    plan = list(map(int, input().split()))
    • ์ „์ฒด ๋„์‹œ ๊ฐœ์ˆ˜ n, ์—ฌํ–‰ ๋„์‹œ ๊ฐœ์ˆ˜ m, ๋„์‹œ ์—ฐ๊ฒฐ ์ •๋ณด graph๋ฅผ ์ž…๋ ฅ๋ฐ›์Šต๋‹ˆ๋‹ค.
    • parent๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ ์ •๋ณด(์ง‘ํ•ฉ ์ •๋ณด)๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

    1. Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜

    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
            return parent[x]
        return x
    
    def union(x, y):
        x = find(x)
        y = find(y)
        if x > y:
            parent[x] = y
        else:
            parent[y] = x

    ์ด ๋ฌธ์ œ๋Š” union-find ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌํ–‰ ๊ณ„ํš์— ์žˆ๋Š” ๋„์‹œ๋“ค์ด ๋ชจ๋‘ ๊ฐ™์€ ์ง‘ํ•ฉ์— ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. 

    ์ด๋•Œ findํ•จ์ˆ˜์—์„œ ๊ฒฝ๋กœ์••์ถ•์„ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ๋กœ์••์ถ•์ด๋ž€, find() ํ•จ์ˆ˜์—์„œ ๋ถ€๋ชจ๋…ธ๋“œ๋ฅผ ์ฐพ์•„๊ฐ€๋Š” ๊ณผ์ •์—์„œ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. Union Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์„ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

     

    Union Find ์•Œ๊ณ ๋ฆฌ์ฆ˜ | ๊ฐœ๋…๊ณผ Python ์ฝ”๋“œ ๊ตฌํ˜„

    ์•ˆ๋…•ํ•˜์„ธ์š”. ์˜ค๋Š˜์€ ๋ฐฑ์ค€์˜ ์นœ๊ตฌ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ์•Œ๊ฒŒ ๋œ union-find ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ๊ธ€์„ ์ž‘์„ฑํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“Œ Union Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€? Union Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์„œ๋กœ์†Œ ์ง‘ํ•ฉ(Disjoint Set)์„ ํ‘œ

    eunbin00.tistory.com

     

    2. ์ง‘ํ•ฉ ๋งŒ๋“ค๊ธฐ

    for idx, connected_nodes in enumerate(graph):
        for v in connected_nodes:
            union(idx + 1, v)

     

    ์ž…๋ ฅ ๋ฐ›์€ ๋„์‹œ ์—ฐ๊ฒฐ ์ •๋ณด(graph)์— ๋”ฐ๋ผ ๋„์‹œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด์žˆ์œผ๋ฉด union()ํ•˜์—ฌ parent ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด๋‚˜๊ฐ‘๋‹ˆ๋‹ค.

    3. ์—ฌํ–‰ ๊ณ„ํš ๊ฒ€์‚ฌ

    result = True
    root = parent[plan[0]]
    for p in plan[1:]:
        if parent[p] != root:
            result = False
            break
    
    if result == True:
        print("YES")
    else:
        print("NO")

     

    ์ž…๋ ฅ๋ฐ›์€ ์—ฌํ–‰ ๊ณ„ํš์—์„œ ๋ชจ๋“  ์—ฌํ–‰ ๊ณ„ํš ๋„์‹œ๊ฐ€ ๊ฐ™์€ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๋ฉด "YES"๋ฅผ ์ถœ๋ ฅ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด "NO"๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. 

     

    ๐ŸŒฑ ์ฝ”๋“œ

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # boj 1976 ์—ฌํ–‰๊ฐ€์ž
    
    n = int(input())
    m = int(input())
    graph = []
    visited = [False] * (n + 1)
    parent = [i for i in range(n + 1)]
    
    for i in range(n):
        graph.append([idx + 1 for idx, i in enumerate(list(map(int, input().split()))) if i == 1])
    
    plan = list(map(int, input().split()))
    
    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
            return parent[x]
        return x
    
    def union(x, y):
        x = find(x)
        y = find(y)
    
        if x > y:
            parent[x] = y
        else:
            parent[y] = x
    
    for idx, connected_nodes in enumerate(graph):
        for v in connected_nodes:
            union(idx + 1, v)
    
    result = True
    root = parent[plan[0]]
    for p in plan[1:]:
        if parent[p] != root:
            result = False
            break
    
    if result == True:
        print("YES")
    else:
        print("NO")
    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€