[Python] boj no. 4195 : 친구 네트워크
Problem
https://www.acmicpc.net/problem/4195
Idea
사용자를 정점으로 친구 관계를 간선으로 생각하면 친구 관계가 주어질 때마다 두 사용자가 속한 트리에 포함된 정점이 몇 개인지 제시해야 한다.
Union-Find를 이용해 rank 배열에 트리에 속한 정점의 수를 저장하는 것으로 풀었다.
Code
import sys
def find(x):
if x != parent[x]:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
x = find(x)
y = find(y)
if x != y:
if rank[x] >= rank[y]:
parent[y] = x
rank[x] += rank[y]
print(rank[x])
else:
parent[x] = y
rank[y] += rank[x]
print(rank[y])
else:
print(rank[x])
t = int(input())
for _ in range(t):
F = int(input())
rank = {}
parent = {}
for _ in range(F):
x, y = sys.stdin.readline().split()
if x not in parent:
parent[x] = x
rank[x] = 1
if y not in parent:
parent[y] = y
rank[y] = 1
union(x, y)
Comment
문제를 풀고나서 다른 해결방법이 있나 찾아보던 도중 기존의 방식에서 조금 더 개선된 Weight Union-Find라는 방식이 있다는 것을 알게 되었다. 기존 Union-Find에서는 부모 정보를 저장하는 배열과 트리의 사이즈를 저장하는 배열을 따로 두는 것과 달리 개선된 방식에서는 두 정보를 하나의 배열에 저장해 메모리 공간을 절반으로 절약할 수 있다. Weight Union-Find 방식에서는 기본적으로 부모 정보를 저장하되 자신이 루트 노드일 경우 -(트리의 사이즈)를 저장한다.