ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 4192] 친구 네트워크 (python 풀이)
    자료구조 & 알고리즘/BOJ 문제풀이 2021. 9. 12. 19:03

     

    1. 문제 

    민혁이는 소셜 네트워크 사이트에서 친구를 만드는 것을 좋아하는 친구이다. 우표를 모으는 취미가 있듯이, 민혁이는 소셜 네트워크 사이트에서 친구를 모으는 것이 취미이다.

    어떤 사이트의 친구 관계가 생긴 순서대로 주어졌을 때, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.

    친구 네트워크란 친구 관계만으로 이동할 수 있는 사이를 말한다.

    2. 입력

    첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진다. 친구 관계는 두 사용자의 아이디로 이루어져 있으며, 알파벳 대문자 또는 소문자로만 이루어진 길이 20 이하의 문자열이다.

    3. 출력

    친구 관계가 생길 때마다, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.

     


    4. 포인트

    1.  기초가 되는 알고리즘인 union - find 알고리즘을 익혀두자   
    2.  dictionary 의 key error 를 막기 위해서는 key를 통한 접근전에 not in 연산자를 통한 검사가 필요하다

     

    4. 문제 풀이

      그래프 부분중 크루스칼 알고리즘 공부중 학습했던 union - find 알고리즘으르 통해 풀 수 있는 문제였다. 

     딕셔너리에 각각의 이름을 key 로 추가하고 값에는 parent 값을 넣어줌으로써 추후 parent를 parent node로 트리가 형성된다.  이렇게 parent를 통해 찾아나가는 것이 find 알고리즘을 이용한 것이고 , 서로 다른 집합을 합치는 uion 함수는 union 알고리즘을 이용한 것이다.  또한 문제에서 요구하는 네트워크에 몇명이 포함 되어 있는지를 반환하기 위해 각 parent를 key로하는 number dictionary 를 만들었다.

     

    number는 parent 를 key로 그리고 parent의 네트워크 크기를 value로 하기때문에 최종적인 값을 구할때는 입력값의 parent를 구해서 number로 조회함을 잊지말자

     

    주의할껀 해당코드 부분이다. 이부분이 빠져도 동작에는 문제없지만 실제로 제출해봤을때 시간초과가 뜬다. 이유를 추론했을때 중간 저 코드로 인해서 range(or depth)가 모두 1이 되어 시간이 많이 단축되는 것 같다.

     

    # 친구 네트워크
    
    def find(name):
        if name == dic[name]:
            return name
        else: 
            p = find(dic[name])
           	## 해당코드 ##
            dic[name] = p
            ######
            return p
    
    def union(name1, name2):
    
        parent1 = find(name1)
        parent2 = find(name2)
    
        if parent1 != parent2 :
            dic[parent2] = parent1
            number[parent1] += number[parent2]
        # parent2 의 부모값을 parent1 으로 바꿔줌으로써
        # 두 tree를 합쳤다고 볼 수 있다.
    case = int(input())
    
    for i in range(case):
        group = int(input())
        
        dic = dict()
        number = dict()
    
        for j in range(group):
            name1 , name2 =  input().split()
            
            if name1 not in dic:
                dic[name1] = name1
                number[name1] = 1
            if name2 not in dic:
                dic[name2] = name2
                number[name2] = 1
    
            union(name1 , name2 )
            
            parent = find(name1 )
            print(number[parent])

    댓글

Designed by Tistory.