https://www.acmicpc.net/problem/21278
문제
컴공 출신은 치킨집을 하게 되어있다. 현실을 부정하지 말고 받아들이면 마음이 편하다. 결국 호석이도 2050년에는 치킨집을 하고 있다. 치킨집 이름은 "호석이 두마리 치킨"이다.
이번에 키친 도시로 분점을 확보하게 된 호석이 두마리 치킨은 도시 안에 2개의 매장을 지으려고 한다. 도시는 N 개의 건물과 M 개의 도로로 이루어져 있다. 건물은 1번부터 N번의 번호를 가지고 있다. i 번째 도로는 서로 다른 두 건물 Ai 번과 Bi 번 사이를 1 시간에 양방향으로 이동할 수 있는 도로이다.
키친 도시에서 2개의 건물을 골라서 치킨집을 열려고 한다. 이 때 아무 곳이나 열 순 없어서 모든 건물에서의 접근성의 합을 최소화하려고 한다. 건물 X 의 접근성은 X 에서 가장 가까운 호석이 두마리 치킨집까지 왕복하는 최단 시간이다. 즉, "모든 건물에서 가장 가까운 치킨집까지 왕복하는 최단 시간의 총합"을 최소화할 수 있는 건물 2개를 골라서 치킨집을 열려고 하는 것이다.
컴공을 졸업한 지 30년이 넘어가는 호석이는 이제 코딩으로 이 문제를 해결할 줄 모른다. 알고리즘 퇴물 호석이를 위해서 최적의 위치가 될 수 있는 건물 2개의 번호와 그 때의 "모든 건물에서 가장 가까운 치킨집까지 왕복하는 최단 시간의 총합"을 출력하자. 만약 이러한 건물 조합이 여러 개라면, 건물 번호 중 작은 게 더 작을수록, 작은 번호가 같다면 큰 번호가 더 작을수록 좋은 건물 조합이다.
입력
첫 번째 줄에 건물의 개수 N과 도로의 개수 M 이 주어진다. 이어서 M 개의 줄에 걸쳐서 도로의 정보 Ai , Bi 가 공백으로 나뉘어서 주어진다. 같은 도로가 중복되어 주어지는 경우는 없다. 어떤 두 건물을 잡아도 도로를 따라서 오고 가는 방법이 존재함이 보장된다.
출력
한 줄에 건물 2개가 지어질 건물 번호를 오름차순으로 출력하고, 그때 모든 도시에서의 왕복 시간의 합을 출력한다.
만약 건물 조합이 다양하게 가능하면, 작은 번호가 더 작은 것을, 작은 번호가 같다면 큰 번호가 더 작은 걸 출력한다.
풀이
Code
import sys
from itertools import combinations
input = sys.stdin.readline
def solution(n, m) :
# 1. 플로이드-워셜을 위한 그래프 생성
graph = [[int(1e9) for _ in range(n+1)] for _ in range(n+1)]
# 2. 간선 정보 입력 받기
for _ in range(m) :
a, b = map(int, input().split())
graph[a][b] = 1
graph[b][a] = 1
# 3. 플로이드-워셜
for k in range(1, n+1) :
for a in range(1, n+1) :
for b in range(1, n+1) :
if a != b :
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
# 4. 조합 리스트 생성
combination = list(combinations(range(1, n+1), 2))
# 5. 정렬
combination.sort(key = lambda x : [sum([2 * min(graph[i][x[0]], graph[i][x[1]]) for i in range(1, n+1) if i not in x]), min(x), max(x)])
n1, n2 = combination[0][0], combination[0][1]
# 6. 결과 출력
print(*combination[0], sum([2 * min(graph[i][n1], graph[i][n2]) for i in range(1, n+1) if i not in (n1, n2)]))
if __name__ == "__main__":
n, m = map(int, input().split())
solution(n, m)
'Coding Test > Baekjoon' 카테고리의 다른 글
[Python/BOJ] 1197. 최소 스패닝 트리 (1) | 2023.10.28 |
---|---|
[Python/BOJ] 1922. 네트워크 연결 (1) | 2023.10.28 |
[Python/BOJ] 14284. 간선 이어가기 2 (1) | 2023.10.28 |
[Python/BOJ] 25602. 캔 주기 (0) | 2023.10.25 |
[Python/BOJ] 15787. 기차가 어둠을 헤치고 은하수를 (1) | 2023.10.23 |