카테고리 없음
[Baekjoon] 백준 15591 - MooTube (Silver) by 파이썬 Python
코딩하는이씨
2024. 12. 1. 20:54
728x90
반응형
https://www.acmicpc.net/problem/15591
문제 설명
그래프와 유니온-파인드를 활용해 특정 조건을 만족하는 노드(동영상)들의 수를 구하는 문제이다.
그래프 구성
- 동영상들은 노드, 동영상 쌍 간의 USADO 값은 간선의 가중치로 주어진다.
- 총 N개의 노드와 N-1개의 간선이 있으며, 모든 노드는 하나의 연결 그래프를 이룬다.
USADO 경로 계산: 두 노드 간의 USADO는 그들을 연결하는 경로의 간선 중 최솟값
아이디어
처음 풀이로 BFS를 사용해 탐색했다. 하지만 시간초과가 발생했다.
따라서 union-find 를 사용해 해결했다. 또한 간선을 내림차순 정렬하여 K 이상의 간선만 처리하도록하여 효율성을 높였다.
코드
노드 u가 속한 집합의 루트노드를 찾는 find 함수이다.
재귀함수를 활용해 부모 노드를 찾고 저장하여 반환한다.
def find(u):
if parent[u] != u:
parent[u] = find(parent[u])
return parent[u]
노드 U와 V가 속한 두 집합을 합치는 union 함수는 아래와 같다.
집합의 크기를 활용하여 작은 집합을 큰 집합에 합친다.
def union(u, v):
u_root = find(u)
v_root = find(v)
if u_root != v_root:
if size[u_root] < size[v_root]:
parent[u_root] = v_root
size[v_root] += size[u_root]
else:
parent[v_root] = u_root
size[u_root] += size[v_root]
간선에 대한 입력 질의를 처리할 때는 K값 이상인 간선을 union-find에 추가하여 계산하도록 하였다.
result = [0] * q
edge_idx = 0
for k_value, v_node, idx in queries:
while edge_idx < len(edges) and edges[edge_idx][0] > k_value:
usado_value, u_node, v_node = edges[edge_idx]
union(u_node, v_node)
edge_idx += 1
root_v = find(v_node)
result[idx] = size[root_v] - 1
전체 코드는 아래와 같다.
import sys
sys.setrecursionlimit(1 << 25)
def find(u):
if parent[u] != u:
parent[u] = find(parent[u])
return parent[u]
def union(u, v):
u_root = find(u)
v_root = find(v)
if u_root != v_root:
if size[u_root] < size[v_root]:
parent[u_root] = v_root
size[v_root] += size[u_root]
else:
parent[v_root] = u_root
size[u_root] += size[v_root]
n, q = map(int, sys.stdin.readline().split())
edges = []
for _ in range(n - 1):
p, node, r = map(int, sys.stdin.readline().split())
edges.append((r, p, node))
queries = []
for i in range(q):
k, v = map(int, sys.stdin.readline().split())
queries.append((k, v, i))
edges.sort(reverse=True)
queries.sort(reverse=True)
parent = [i for i in range(n + 1)]
size = [1] * (n + 1)
result = [0] * q
edge_idx = 0
for k_value, v_node, idx in queries:
# 현재 K 값 이상인 간선을 유니온 파인드에 추가
while edge_idx < len(edges) and edges[edge_idx][0] >= k_value:
usado_value, u_node, v_node_edge = edges[edge_idx]
union(u_node, v_node_edge)
edge_idx += 1
root_v = find(v_node)
result[idx] = size[root_v] - 1 # 시작 노드를 제외한 연결된 노드의 수
for res in result:
print(res)
728x90
반응형