백준
(python) 백준 16562 - 친구비
komizke
2023. 1. 14. 00:00
https://www.acmicpc.net/problem/16562
16562번: 친구비
첫 줄에 학생 수 N (1 ≤ N ≤ 10,000)과 친구관계 수 M (0 ≤ M ≤ 10,000), 가지고 있는 돈 k (1 ≤ k ≤ 10,000,000)가 주어진다. 두번째 줄에 N개의 각각의 학생이 원하는 친구비 Ai가 주어진다. (1 ≤ Ai ≤ 10,
www.acmicpc.net
1. 문제 설명
특정 비용을 지불하여 친구를 사귀며 친구의 친구를 친구로 인정한다.
친구 전부를 사귈 수 있는 최소 비용을 구하는 문제
2. 문제 풀이
한 친구를 사귄다면 다른 친구 또한 사귀게 되는 원리이다.
그러므로 친구 관계를 형성하는 번호끼리 구분을 해줄 필요가 있다.
유니온 - 파인드 알고리즘을 활용하여 최소비용을 구하는 문제이기에
비용이 적은 번호를 기준으로 합친다.
더 적은 비용의 번호가 부모노드가 되며 다른 노드의 비용은 0으로 초기화한다.
(친구의 친구는 친구가 된다는 원리로 인하여)
아래는 유니온 - 파인드 알고리즘이다.
def get_parent(x):
if parent[x] == x:
return x
parent[x] = get_parent(parent[x])
return parent[x]
def union(x,y):
x_parent = get_parent(x)
y_parent = get_parent(y)
if cost[x_parent] > cost[y_parent]:
cost[x_parent] = 0
parent[x_parent] = y_parent
else:
cost[y_parent] = 0
parent[y_parent] = x_parent
3. 전체 코드
def get_parent(x):
if parent[x] == x:
return x
parent[x] = get_parent(parent[x])
return parent[x]
def union(x,y): #더 작은 비용을 기준으로 병합
x_parent = get_parent(x)
y_parent = get_parent(y)
if cost[x_parent] > cost[y_parent]:
cost[x_parent] = 0
parent[x_parent] = y_parent
else:
cost[y_parent] = 0
parent[y_parent] = x_parent
n, m, k = map(int, input().split())
cost = [0] #친구비 리스트
for c in list(map(int, input().split())):
cost.append(c)
parent = [i for i in range(n+1)] #부모 노드 저장할 리스트
for _ in range(m):
v, w = map(int, input().split())
union(v, w)
total_cost = sum(cost)
#총 비용이 예산보다 크다면 친구 다 사귈 수 없다.
if total_cost <= k:
print(total_cost)
else:
print("Oh no")