새소식

PS/백준

[백준/1414] 불우이웃돕기 (Python)

  • -

Problem : https://www.acmicpc.net/problem/1414

 

1414번: 불우이웃돕기

첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 랜선의 길이가 주어진다. i번째 줄의 j번째 문자가 0인 경우는 컴퓨터 i와 컴퓨터 j를 연결하는 랜선이 없음을 의미한다. 그 외의 경우는 랜선

www.acmicpc.net

 

Difficulty : Gold 3

 

Status : Solved

 

Time : 00:13:06

 


 

문제 설명

 

더보기

 

다솜이는 불우이웃 돕기 활동을 하기 위해 무엇을 할지 생각했다. 마침 집에 엄청나게 많은 랜선이 있다는 것을 깨달았다. 마침 랜선이 이렇게 많이 필요 없다고 느낀 다솜이는 랜선을 지역사회에 봉사하기로 했다.

다솜이의 집에는 N개의 방이 있다. 각각의 방에는 모두 한 개의 컴퓨터가 있다. 각각의 컴퓨터는 랜선으로 연결되어 있다. 어떤 컴퓨터 A와 컴퓨터 B가 있을 때, A와 B가 서로 랜선으로 연결되어 있거나, 또 다른 컴퓨터를 통해서 연결이 되어있으면 서로 통신을 할 수 있다.

다솜이는 집 안에 있는 N개의 컴퓨터를 모두 서로 연결되게 하고 싶다.

N개의 컴퓨터가 서로 연결되어 있는 랜선의 길이가 주어질 때, 다솜이가 기부할 수 있는 랜선의 길이의 최댓값을 출력하는 프로그램을 작성하시오.

 

 

입력 및 출력

 

더보기

입력

 

첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 랜선의 길이가 주어진다. i번째 줄의 j번째 문자가 0인 경우는 컴퓨터 i와 컴퓨터 j를 연결하는 랜선이 없음을 의미한다. 그 외의 경우는 랜선의 길이를 의미한다. 랜선의 길이는 a부터 z는 1부터 26을 나타내고, A부터 Z는 27부터 52를 나타낸다. N은 50보다 작거나 같은 자연수이다.

 

출력

 

첫째 줄에 다솜이가 기부할 수 있는 랜선의 길이의 최댓값을 출력한다. 만약, 모든 컴퓨터가 연결되어 있지 않으면 -1을 출력한다.

 

입력 예시

 

3
abc
def
ghi

 

출력 예시

 

40

 

 


 

풀이

 

  1. 들어가기에 앞서, a-z, A-Z 케이스를 정상적으로 해당하는 정수값으로 반환하는 데 주의하자. ord('a')와 ord('A')를 사용하면 간편하다.
  2. 최대한 많은 랜선을 기부하려면, 컴퓨터의 연결을 유지하면서 최소 랜선으로 네트워크를 구성해야 한다. 즉 MST 형태를 갖추어야 한다. 이 때, 최소 스패닝 트리를 연결하지 않은 모든 노드들의 합이 정답이 된다.
  3. 또한, 이 MST를 구할 때, 모든 노드가 같은 트리에 속할 수 있는지를 검사해야 한다. 프림 알고리즘을 사용하였다면 visited 배열로, 크루스칼 알고리즘을 사용하였다면 parents의 개수 여부로 판별할 수 있다.

 

 

풀이 코드

from heapq import heappush, heappop
import sys
input = sys.stdin.readline

N = int(input())
q = list()
parents = list(range(N))
total = 0

for i in range(N) :
  maps = input().strip()
  for j in range(N) :
    if maps[j] != '0' :
      if ord(maps[j]) >= ord('a') :
        cable = ord(maps[j]) - ord('a') + 1
      else :
        cable = ord(maps[j]) - ord('A') + 27
      heappush(q, (cable, i, j))
      total += cable

def find(a) :
  if a == parents[a] :
    return a

  parents[a] = find(parents[a])
  return parents[a]

def union(pa, pb) :
  if pa < pb :
    parents[pb] = pa
  else :
    parents[pa] = pb

cnt = N-1
while q and cnt :
  cable, a, b = heappop(q)
  pa = find(a)
  pb = find(b)
  if pa != pb :
    union(pa, pb)
    cnt -= 1
    total -= cable

for i in range(N) :
  find(i)
parent_set = set(parents)
print(total if len(parent_set) < 2 else -1)

풀이 완료!

'PS > 백준' 카테고리의 다른 글

[백준/1275] 커피숍2 (Python)  (1) 2023.10.27
[백준/1493] 박스 채우기 (Python)  (1) 2023.10.26
[백준/1069] 집으로 (Python)  (1) 2023.10.24
[백준/1034] 램프 (Python)  (1) 2023.10.24
[백준/1922] 네트워크 연결 (Python)  (1) 2023.10.22
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.