본문 바로가기
알고리즘 풀기

[백준] 1414 불우이웃돕기 python3

by 쏘야.yap 2020. 2. 29.
728x90

문제 : https://www.acmicpc.net/problem/1414

 

1414번: 불우이웃돕기

첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 인접행렬식으로 랜선의 길이의 정보가 주어진다. 0은 연결되어있지 않음을 나타내고, 랜선의 길이는 a부터 z는 1부터 26을 나타내고, A부터 Z는 27부터 52를 나타낸다. N은 100보다 작거나 같은 자연수이다.

www.acmicpc.net

 

최소신장트리를 만들고, 그 weight의 합을 구하는 문제다. (노드: 컴퓨터, 간선: 랜선)

트리를 만들기 전에 다솜이네 집의 총 랜선길이를 구하고, 만들어진 최소신장트리의 weight 총합을 빼면 되겠다.

나는 크루스칼 알고리즘을 사용하여 풀었다.

python3 코드

def make_egdes():
    total_weight = 0
    for i in range(N):
        row = input()
        for j in range(N):
            if ord('a') <= ord(row[j]) <= ord('z'):
                weight = ord(row[j]) - ord('a') + 1
            elif ord('A') <= ord(row[j]) <= ord('Z'):
                weight = ord(row[j]) - ord('A') + 27
            else:
                weight = 0

            if weight != 0:
                edges.append((weight, i, j))
                total_weight += weight
    return total_weight


def make_roots():
    for i in range(N):
        roots[i] = i
        sizes[i] = 1


def find_root(v):
    # if v != roots[v]:
    #     return find_root(roots[v])
    # return roots[v]
    while v != roots[v]:
        v = roots[v]
    return roots[v]


def union(v_root, u_root):
    if sizes[v_root] < sizes[u_root]:
        roots[v_root] = u_root
        sizes[u_root] += sizes[v_root]
    else:
        roots[u_root] = v_root
        sizes[v_root] += sizes[u_root]


def kruskal():
    minimum_spanning_tree = []

    # 각 정점을 독립 집합화 하고
    make_roots()

    # 엣지를 오름차순 정렬하고
    sorted_edges = sorted(edges, key = lambda edge: edge[0])

    for edge in sorted_edges:
        # 최소 엣지의 양끝노드를 꺼내서
        weight, v, u = edge

        # 루트가 다르면
        v_root         = find_root(v)
        u_root = find_root(u)

        if v_root != u_root:
            # 합친다
            union(v_root, u_root)
            # 그리고 mst에 추가한다
            minimum_spanning_tree.append(edge)

        # mst의 크기가 N-1이면 종료
        if len(minimum_spanning_tree) == N-1:
            break

    if len(minimum_spanning_tree) < N-1: # 트리가 만들어지지 않음
        return -1
    else:
        return minimum_spanning_tree


N = int(input())

roots = {}
sizes = {}
edges = []

total_weight = make_egdes() # egdes 채우고 가진 랜선길이 return
mst = kruskal()

if mst == -1:
    print(mst)
else:
    sum = 0
    for edge in mst:
        sum += edge[0]

    print(total_weight - sum)

 

자랑

여담인데 Python3 최초 정답자다 (신나서 춤추는 이모티콘) 

'알고리즘 풀기' 카테고리의 다른 글

[백준] 1967 트리의 지름 python3  (0) 2020.03.10
[백준] 14501 퇴사 python3  (0) 2020.03.08
[백준] 2875 대회or인턴 python3  (0) 2020.02.29
코테) 기능개발  (0) 2019.12.18