기록

백준_1647_도시 분할 계획 본문

코딩테스트/python

백준_1647_도시 분할 계획

zyin 2022. 10. 6. 14:46

문제

 

1647번: 도시 분할 계획

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

www.acmicpc.net

풀이

1) 크루스칼 알고리즘

 

크러스컬 알고리즘 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 과학에서 크러스컬 알고리즘(영어: Kruskal’s algorithm)은 최소 비용 신장 부분 트리를 찾는 알고리즘이다. 변의 개수를 E {\displaystyle E} , 꼭짓점의 개수를 V

ko.wikipedia.org

1. 간선을 비용이 적은 것부터 오름차순으로 정렬한다.

2. 각 간선이 사이클을 발생시키는지 확인한다.

2-1. 사이클을 발생시키지 않는다면 신장 트리에 포함한다.

2-2. 사이클을 발생시키지 않는다면 신장 트리에 포함하지 않는다.

그래프를 둘로 나누어야 하므로, 선택된 간선 중에 유지 비용이 제일 큰 간선 하나를 제거한다.

코드

import sys
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline

N, M = map(int, input().split())
stack = list()
for _ in range(M):
    n, m, v = map(int, input().split())
    stack.append((v, n, m))

## union & find
parent = [i for i in range(N + 1)]

def find(n):
    if parent[n] == n: return n
    parent[n] = find(parent[n])
    return parent[n]

def join(n, m):
    n = find(n)
    m = find(m)
    parent[max(n, m)] = min(n, m)

## Kruskal
result = 0
maxWeight = 0
stack.sort()
for v, n, m in stack:
    if find(n) != find(m):  # 사이클이 발생하지 않는 경우에만
        join(n, m)
        result += v
        maxWeight = max(maxWeight, v)  # 선택된 간선 중 최대 비용을 저장

print(result - maxWeight)  # 그래프를 둘로 나누므로, 가장 큰 값을 제거
Comments