티스토리 뷰

코딩테스트

도시 분할 계획

ajaa 2024. 11. 14. 20:08

📌문제

마을은 N개의 집과 그 집들을 연결하는 M개의 길로 이루어져 있다. 마을의 이장은 마을을 2개의 분리된 마을로 분할할 계획을 세우고 있다. 마을을 분할할 때는 각 분할된 마을 안에 집들이 서로 연결되도록 분할해야 한다.

마을의 이장은 계획을 세우다 마을 안에 길이 너무 많다는 생각을 했다. 일단 분리된 두 마을 사이 길은 필요 없으므로 없앨 수 있다. 그리고 각 분리된 마을 안에서도 임의의 두 집 사이에 경로가 항상 존재하게 하면서 길을 더 없앨 수 있다. 위 조건을 만족하도록 길들을 모두 없애고 나머지 길의 유지비의 합을 최소로 하는 프로그램을 작성하시오.

 

📌풀이

전체 그래프에서 2개의 최소 신장 트리 만들어야 함

크루스칼 알고리즘으로 최소 신장 트리를 찾은 뒤에 최소 신장 트리를 구성하는 간선 중 가장 비용이 큰 간선을 제거

 

📌코드

# 특정 원소가 속한 집합 찾기
def find_parent(parent, x):
    # 루트 노드 아니라면 루트노드 찾을 때까지 재귀 호출
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x])
    return parent[x]


# 두 원소가 속한 집합 합치기
def union_parent(parent, a, b):
    a = find_parent(parent, a)
    b = find_parent(parent, b)
    if a < b:
        parent[b] = a
    else:
        parent[a] = b


# 노드의 개수, 간선의 개수 입력
v, e = map(int, input().split())
parent = [0] * (v + 1)

# 모든 간선을 담을 리스트와 최종 비용 담을 변수
edges = []
result = 0

# 부모 테이블에서 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
    parent[i] = i

# 간선 입력
for _ in range(e):
    a, b, cost = map(int, input().split())
    # 비용순으로 정렬학 위해 튜플의 첫번째 원소를 비용으로 설정
    edges.append((cost, a, b))

# 간선을 비용순으로 정렬
edges.sort()
last = 0  # 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선

# 간선을 하나씩 확인하며
for edge in edges:
    cost, a, b = edge
    # 사이클이 발생하지 않는 경우만 집합 포함
    if find_parent(parent, a) != find_parent(parent, b):
        union_parent(parent, a, b)
        result += cost
        last = cost

print(result - last)  # 비용 가장 큰 마지막 cost를 제거

 

 

📌참고

https://g.co/kgs/eyd5SSd

 

이것이 취업을 위한 코딩 테스트다 with 파이썬

IT 취준생이라면 누구나 입사하고 싶은 카카오・삼성전자・네이버・라인!취업의 성공 열쇠는 알고리즘 인터뷰에 있다! IT 취준생이라면 누구나 가고 싶어 하는 카카오, 라인, 삼성전자의 2016년

www.google.com

 

 

'코딩테스트' 카테고리의 다른 글

모험가 길드  (6) 2024.11.16
커리큘럼  (1) 2024.11.15
팀 결성  (1) 2024.11.13
위상 정렬  (1) 2024.11.12
신장 트리, 크루스칼 알고리즘  (1) 2024.11.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함