알고리즘 풀이/백준

[백준 1647] 도시 분할 계획

mhko411 2021. 4. 24. 19:56
728x90

문제

어떤 마을은 N개의 집과 그 집들을 연결하는 M개의 길로 이루어져있다. 각 길은 유지비가 들고있으며 마을을 두 개의 마을로 분할할 계획을 갖고있다. 

마을에는 집이 하나 이상 있어야하고 분리된 두 마을 사이에 있는 길들도 필요없으므로 없앨 수 있다. 그리고 각 분리된 마을 안에서도 임의의 두 집 사이에 경로가 항상 존재하게 하면서 길을 더 없앨 수 있을 때 나머지 길 유지비의 합을 최소로 되도록 하라.

 

입력

첫째 줄에 집의 개수N, 길의 개수M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번 집과 B번 집을 연결하는 길의 유지비가 C (1 ≤ C ≤ 1,000)라는 뜻이다.

 

출력

첫째 줄에 없애고 남은 길 유지비의 합의 최솟값을 출력한다.


접근

분리된 마을에서 각 마을은 하나 이상의 집이 무조건 있어야한다. 그리고 분리된 마을은 연결할 필요가 없다. 그리고 나머지 길을 최소로 해야하기 때문에 N개의 마을의 최소 신장 트리를 구한다. 하지만 마을을 두 개로 분리해야하기 때문에 N-2개의 간선을 선택하는 크루스칼 알고리즘을 적용한다.

 

기존에 N-1개의 간선을 선택하는 것은 모든 집을 연결할 때의 최소 신장 트리가 아닌 N-2개를 선택하여 한 개의 집은 연결이 안되도록 한다.

 

구현

- 그래프를 입력받고 비용을 기준으로 오름차순 정렬한다.

for _ in range(M):
    a, b, c = map(int, input().split())
    a -= 1
    b -= 1
    graph.append((a, b, c))

graph = sorted(graph, key=lambda x: x[2])

 

- a집과 b집의 루트 노드가 다를 때 두 집을 연결하며 연결한 간선의 수가 N-2개 일때 종료한다.

- N-2개를 선택했을 때가 최소 비용으로 마을을 분리하는 경우이다.

edge_count = 0
answer = 0

for a, b, c in graph:
    if find_set(a) != find_set(b):
        union(a, b)
        edge_count += 1
        answer += c

    if edge_count == N-2:
        break

전체 코드

import sys
input = sys.stdin.readline

def find_set(a):
    if p[a] == a:
        return a
    else:
        b = find_set(p[a])
        p[a] = b
        return b

def union(a, b):
    a = find_set(a)
    b = find_set(b)
    if a != b:
        p[b] = a

N, M = map(int, input().split())
p = [n for n in range(N)]
graph = []
for _ in range(M):
    a, b, c = map(int, input().split())
    a -= 1
    b -= 1
    graph.append((a, b, c))

graph = sorted(graph, key=lambda x: x[2])

edge_count = 0
answer = 0

for a, b, c in graph:
    if find_set(a) != find_set(b):
        union(a, b)
        edge_count += 1
        answer += c

    if edge_count == N-2:
        break

print(answer)

'알고리즘 풀이 > 백준' 카테고리의 다른 글

[백준 10282] 해킹  (0) 2021.04.24
[백준 1238] 파티  (0) 2021.04.24
[백준 1504] 특정한 최단 경로  (0) 2021.04.23
[백준 6497] 전력난  (0) 2021.04.23
[백준 1976] 여행가자  (0) 2021.04.23