관리 메뉴

공부 기록장 💻

[알고리즘] 전력망을 둘로 나누기 (프로그래머스 완전탐색 Level 2 - DFS 활용) 본문

# CS Study/Algorithms

[알고리즘] 전력망을 둘로 나누기 (프로그래머스 완전탐색 Level 2 - DFS 활용)

dream_for 2023. 4. 15. 01:05

전력망을 둘로 나누기

 

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

 

문제 설명

n개의 송전탑이 전선을 통해 하나의 트리 형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.

송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절대값)를 return 하도록 solution 함수를 완성해주세요.


제한사항
  • n은 2 이상 100 이하인 자연수입니다.
  • wires는 길이가 n-1인 정수형 2차원 배열입니다.
    • wires의 각 원소는 [v1, v2] 2개의 자연수로 이루어져 있으며, 이는 전력망의 v1번 송전탑과 v2번 송전탑이 전선으로 연결되어 있다는 것을 의미합니다.
    • 1 ≤ v1 < v2 ≤ n 입니다.
    • 전력망 네트워크가 하나의 트리 형태가 아닌 경우는 입력으로 주어지지 않습니다.

입출력 예

w wires result
9 [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] 3
4 [[1,2],[2,3],[3,4]] 0
7 [[1,2],[2,7],[3,7],[3,4],[4,5],[6,7]] 1

 

입출력 예 설명

입출력 예 #1

  • 다음 그림은 주어진 입력을 해결하는 방법 중 하나를 나타낸 것입니다.
  • 4번과 7번을 연결하는 전선을 끊으면 두 전력망은 각 6개와 3개의 송전탑을 가지며, 이보다 더 비슷한 개수로 전력망을 나눌 수 없습니다.
  • 또 다른 방법으로는 3번과 4번을 연결하는 전선을 끊어도 최선의 정답을 도출할 수 있습니다.

입출력 예 #2

  • 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
  • 2번과 3번을 연결하는 전선을 끊으면 두 전력망이 모두 2개의 송전탑을 가지게 되며, 이 방법이 최선입니다.

입출력 예 #3

  • 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
  • 3번과 7번을 연결하는 전선을 끊으면 두 전력망이 각각 4개와 3개의 송전탑을 가지게 되며, 이 방법이 최선입니다.

 

 

문제 접근 방식 및 풀이

 

Union find 를 이용해 나뉘어진 트리의 부모(루트 노드)를 이용하는 방법도 있지만,

간단하게 DFS 깊이 우선 탐색을 이용해 한 트리에 속해 있는 자식 노드들의 개수를 구하는 방법으로 문제를 해결하였다.

분리된 두 트리 중 한 트리의 노드 개수를 세는 접근 방식으로, 두 트리의 노드의 개수 차이 중 가장 적은 값을 최종 결과로 도출하였다.

 

전체 소스 코드

 

def dfs(cur,wires,ch):
    global tmp
    
    for i in range(len(ch)-1):
        if ch[i]==0:
            for j in range(2):
                if wires[i][j]==cur:
                    ch[i]=1
                    tmp+=1
                    dfs(wires[i][(j+1)%2],wires,ch)
                    ch[i]=0 # backtracking
    
def solution(n, wires):
    ch = [0]*n
    res = []
    global tmp
    
    # 분리된 두 트리 중 한 트리의 노드 개수 세기
    for i in range(n-1):
        tmp=1
        ch[i]=1 # i번째 선을 끊었을때 기준으로 루트 노드로 갖는 두 개의 트리가 생성 
        a,b = wires[i][0], wires[i][1]
        
        dfs(a,wires,ch) # 루트노드 a 트리의 노드 개수
        ch[i]=0
        res.append(abs(2*tmp-n)) # 두 트리의 노드 개수 차이
    return min(res)
728x90
반응형
Comments