[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ์ „๋ ฅ๋ง์„ ๋‘˜๋กœ ๋‚˜๋ˆ„๊ธฐ (Python, BFS, ์™„์ „ํƒ์ƒ‰)

    ๋ฐ˜์‘ํ˜•

     

     

    ๐ŸŒฑ ๋ฌธ์ œ

    https://school.programmers.co.kr/learn/courses/30/lessons/86971

     

    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

    ์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

    programmers.co.kr

     

     

     

    ๐ŸŒฑ ํ’€์ด

    n์€ 2 ์ด์ƒ 100 ์ดํ•˜์ธ ์ž์—ฐ์ˆ˜์ด๊ณ  wires๋Š” ๊ธธ์ด๊ฐ€ n-1์ธ 2์ฐจ์› ๋ฐฐ์—ด๋กœ, ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ $O(100^2)$์„ ๋„˜์ง€ ์•Š์œผ๋ฏ€๋กœ (n-1 ๋ฐฐ์—ด ํƒ์ƒ‰($O(N)$) * BFS ์‹œ๊ฐ„๋ณต์žก๋„($O(N)$)) ์™„์ „ ํƒ์ƒ‰์„ ์ด์šฉํ•ด์„œ ํ’€์ดํ•ฉ๋‹ˆ๋‹ค.

    1. ์ „๋ ฅ๋ง(graph) ์ •๋ณด๋ฅผ 2์ฐจ์› ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ

    graph = [[] for _ in range(n + 1)]
    for wire in wires:
        graph[wire[0]].append(wire[1])
        graph[wire[1]].append(wire[0])

     

    2. ์ „๋ ฅ๋ง์„ ํ•˜๋‚˜์”ฉ ๋Š์–ด๋ณด๊ธฐ - ๋ชจ๋“  ๊ฒฝ์šฐ ํƒ์ƒ‰(์™„์ „ ํƒ์ƒ‰)

    wires๋ฅผ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋Œ๋ฉด์„œ ์ „๋ ฅ๋ง์„ ํ•˜๋‚˜์”ฉ ๋Š์–ด๋ด…๋‹ˆ๋‹ค. ์ด๋•Œ, graph ์ •๋ณด๋ฅผ deepcopyํ•ด์„œ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ ์ •๋ณด๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ๋„ ์›๋ž˜ graph ์ •๋ณด์—๋Š” ๋ณ€ํ™”๊ฐ€ ์—†๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

    for wire in wires:
        graph_ = deepcopy(graph)
        graph_[wire[0]].remove(wire[1])
        graph_[wire[1]].remove(wire[0])

     

    3. ๊ฐ ์ „๋ ฅ๋ง์— ์žˆ๋Š” ์†ก์ „ํƒ‘์˜ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ

    ์ „๋ ฅ๋ง์„ ๋Š์œผ๋ฉด ํ•˜๋‚˜์˜ ์ „๋ ฅ๋ง์ด ๋‘˜๋กœ ์ชผ๊ฐœ์ง‘๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‘˜๋กœ ์ชผ๊ฐœ์–ด์ง„ ๊ฐ ์ „๋ ฅ๋ง(๊ทธ๋ž˜ํ”„)์—์„œ ์†ก์ „ํƒ‘(๋…ธ๋“œ)์ด ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์นด์šดํŠธ ํ•œ ํ›„, ๊ทธ ์ฐจ์ด๋ฅผ ๊ตฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” DFS๋‚˜ BFS๋กœ ์…€ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ €๋Š” BFS๋กœ ๊ตฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    def bfs(graph, start):
        count = 1
        queue = deque([start])
        visited = [False] * (len(graph) + 1)
        visited[start] = True
    
        while queue:
            v = queue.popleft()
            for node in graph[v]:
                if not visited[node]:
                    visited[node] = True
                    queue.append(node)
    
            count += 1
    
        return count

    BFS์— ๋“ค์–ด๊ฐ€๋Š” ์‹œ์ž‘๋…ธ๋“œ๋Š” ๋Š์€ wire์˜ ๋‘ ๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ์‹œ์ž‘๋…ธ๋“œ๋กœ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    count1, count2 = bfs(graph_, wire[0]), bfs(graph_, wire[1])

     

     

     

    ๐ŸŒฑ ์ •๋‹ต ์ฝ”๋“œ 

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # programmers ์ „๋ ฅ๋ง์„ ๋‘˜๋กœ ๋‚˜๋ˆ„๊ธฐ
    
    from collections import deque
    from copy import deepcopy
    
    
    # ํ•˜๋‚˜์˜ ์ „๋ ฅ๋ง์— ๋ช‡ ๊ฐœ์˜ ์†ก์ „ํƒ‘์ด ์žˆ๋Š”์ง€ ์„ธ๊ธฐ
    def bfs(graph, start):
        count = 1
        queue = deque([start])
        visited = [False] * (len(graph) + 1)
        visited[start] = True
    
        while queue:
            v = queue.popleft()
            for node in graph[v]:
                if not visited[node]:
                    visited[node] = True
                    queue.append(node)
    
            count += 1
    
        return count
    
    
    def solution(n, wires):
        answer = 100
    
        graph = [[] for _ in range(n + 1)]
        for wire in wires:
            graph[wire[0]].append(wire[1])
            graph[wire[1]].append(wire[0])
    
        for wire in wires:
            graph_ = deepcopy(graph)
            graph_[wire[0]].remove(wire[1])
            graph_[wire[1]].remove(wire[0])
    
            count1, count2 = bfs(graph_, wire[0]), bfs(graph_, wire[1])
    
            res = abs(count1 - count2)
            if res < answer:
                answer = res
    
        return answer
    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€