문제
민혁이는 소셜 네트워크 사이트에서 친구를 만드는 것을 좋아하는 친구이다. 우표를 모으는 취미가 있듯이, 민혁이는 소셜 네트워크 사이트에서 친구를 모으는 것이 취미이다.
어떤 사이트의 친구 관계가 생긴 순서대로 주어졌을 때, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.
친구 네트워크란 친구 관계만으로 이동할 수 있는 사이를 말한다.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진다. 친구 관계는 두 사용자의 아이디로 이루어져 있으며, 알파벳 대문자 또는 소문자로만 이루어진 길이 20 이하의 문자열이다.
출력
친구 관계가 생길 때마다, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.
반응형
풀이
test_case = int(input())
# find 재귀 함수 : x의 찐부모를 찾을 떄 까지 find
def find(x):
if x == parent[x]:
return x
else:
parent[x] = find(parent[x])
return parent[x]
# x의 부모를 찾고, y의 부모를 찾음. 서로 부모가 다르면 x의 부모를 일치시킴.
def union(x, y):
x_ = find(x)
y_ = find(y)
# x, y 의 부모가 서로 다른 경우, x 부모로 일치. num 딕셔너리에 자식 수 셈.
if x_ != y_:
parent[y_] = x_
num[x_] += num[y_]
for _ in range(test_case):
friends = int(input())
parent = dict()
num = dict()
for _ in range(friends):
x, y = input().split()
if x not in parent:
parent[x] = x
num[x] = 1
if y not in parent:
parent[y] = y
num[y] = 1
union(x, y)
print(num[find(x)])
- 처음 문제를 읽을 때, 뭔 개소리를 하는지 모르겠었다... Union-Find의 개념이 없으면 이해를 못할 것 같은 느낌... 그리고 헷갈리고 애매한게 많다... 갑자기 "두 사람"을 말하길래 누굴 말하는 건지 생각하다가 먼 산으로 갈 뻔했다, 테스트 케이스를 2개 줘서 "두 사람의 친구 네트워크"라고 한 것 같다.... 그래프 개수가 여러개면 어떤 그래프의 친구 수가 출력 되어야 하는 것도 그러하다...
- Union-Find 문제 (부모(parent)와 자식(child) 테이블 존재) / 친구 이름을 입력 받을 때, (x, y)를 받는다고 하면, x <- y 의 방향으로 부모와 자식 관계를 형성 (부모 <- 자식). 예를 들면, 처음 Fred Barney라는 입력은 "Fred <- Barney", 두 번째로 Barney Betty 입력은 "Fred <- Betty"가 된다. "Fred <- Barney <- Betty " 결국엔 "Fred <- Betty"가 된다. 즉, Fred가 최종 부모인 역할임. (그림으로 이해하면 더 쉽다. 친구를 노드로 생각해서 그린 뒤에 화살표를 붙임) 그럼 이 상황에서 출력을 생각하면, Fred라는 부모는 Barney와 Betty까지 총 3명으로 네트워크를 구성했다. 문제에서 입력으로 준 두 번째 케이스는, 두 번째 줄에서, 두 개의 친구 네트워크로 구성된 후, 마지막에 Barney와 Betty가 친구가 되면서 모든 친구들이 Fred를 부모로 갖게 된다. "Fred <- Barney <- Betty <- Wilma" = 총 4명으로 구성
- Union-Find의 개념을 살짝 말하자면, dictionary 자료형의 key와 value 값을, key는 모든 구성원(=노드), value는 그 구성원의 부모를 나타낸다. (dict['구성원'] = 부모) >> 노드의 부모가 달라질 수 있기 떄문에 이러한 구조
- parent 딕셔너리는 {자기 이름:부모} 의 구조로 있음. (부모 갱신 됨)
- num 딕셔너리는 {자기 이름:숫자}의 구조이지만, 결국 부모가 되는 이름에 숫자가 쌓임
- 풀이한 코드로 최종 parent 를 출력해보면 Wilma의 부모가 Betty라고 나오는데, 코드 상, 마지막에 wilma의 찐부모를 찾는 find함수가 실행되지 않음.(=그럴 필요가 없음) 답을 위한 코드로는 맞지만, 개념적으로는 틀림. num로 구성원 수를 출력했기 때문에 문제 없음. 다음 입력이 또 주어지면 알아서 정리됨. >> 더 좋은 코드를 생각 못하겠음.
출처
Contest > Waterloo's local Programming Contests > 27 September, 2008 C번
'What is Computer? > Data structure & Algorithm' 카테고리의 다른 글
[Python] 백준 '꽃길' 14620번 | 방향 벡터, 브루트 포스, DFS 알고리즘 문제 (0) | 2022.10.11 |
---|---|
[Python] 백준 '늑대와 양' 16956번 | 방향벡터 알고리즘 문제 (0) | 2022.10.10 |
[Python] 백준 '수 찾기' 1920번| 해쉬, 배열, 구현 자료구조 (0) | 2022.10.10 |
[Python] 백준 'SHA-256' 10930번 | 해시, 구현 자료구조 문제 (0) | 2022.10.08 |
[Python] 백준 '키로거' 5397 | 스택, 구현, 그리디 자료구조 문제 (0) | 2022.10.03 |