국문과 유목민

[그래프] 도시 분할 계획 본문

알고리즘_코딩테스트/이것이 코딩테스트다

[그래프] 도시 분할 계획

논곰 2021. 12. 8. 00:15

1. 문제 설명

마을을 2개로 나누려고 하는데 가장 효율적으로 나눌 수 있는 방법을 찾는 문제

- 핵심 아이디어는 전체 그래프에서 2개의 최소 신장 트리를 만들어야 한다. 

- 마을을 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 = [i for i in range(v+1)]

edges = []
for _ in range(e):
    a, b, cost = map(int, input().split())
    edges.append((cost, a, b))
    
# 비용이 낮은 순으로 정렬
edges.sort()

result = []

for edge in edges:
    cost, a, b = edge
    if find_parent(parent, a) != find_parent(parent, b):
        union_parent(parent, a, b)
        result.append(cost)
        
result.pop()
sum(result)

"""
7 12
1 2 3
1 3 2
3 2 1
2 5 2
3 4 4
7 3 6
5 1 5
1 6 2
6 4 1
6 5 3
4 5 3
6 7 4
>> 8
"""

3. 코멘트

- 리스트에 넣을 때, 후에 비용 순으로 정렬할 것을 생각해서 입력할 때부터 고려해야 한다.

'알고리즘_코딩테스트 > 이것이 코딩테스트다' 카테고리의 다른 글

[그리드] 모험가 길드  (0) 2021.12.12
[그래프] 커리큘럼  (0) 2021.12.08
[그래프] 팀 결성  (0) 2021.12.07
[최단경로] 전보  (0) 2021.12.07
[최단경로] 미래도시  (0) 2021.12.07
Comments