Problem Solving/항해99
99클럽 코테 스터디 3일차 TIL, Floyd-Warshall
wrathlion
2024. 10. 30. 18:33
- 문제: Baekjoon2660: 회장뽑기
- 설명: 그래프가 주어질 때 다른 노드까지의 가장 큰 최단 거리가 가장 작은 노드들을 구하여라
- 다시 설명하자면 한 노드에서 모든 노드들까지의 최단 거리를 구하자. 그리고 한 노드의 점수는 이 최단 거리 중 가장 큰 값이다.
- 예) 1번 노드와 2번 노드의 최단 거리가 2, 1번 노드와 3번 노드의 최단 거리가 3이면 1번 노드의 점수는 3이다.
- 최종적으로 점수가 가장 작은 노드들을 구하는 문제이다.
- 풀이
- 일단 모든 노드 쌍의 최단 거리를 구하여야하니 Floyd-Warshall을 적용한다.
- 각 점수에 속하는 노드들을 배열에 저장한다.
- 가장 작은 점수에 속하는 노드들을 출력한다.
- 오늘의 회고
- range로 모든 인덱스 탐색하는 형태를 쓰고 싶지 않은데 그렇다고 슬라이싱 또한 쓰고 싶지 않아서 굉장히 딜레마이다.
- range를 안쓴다면...
for idx, adj in enumerate(adj_mat[1:]): score = max(adj[1:]) friend_list[score].append(idx)
- range를 쓴다면...
for i in range(1, n + 1): score = max(adj_mat[i][1:]) friend_list[score].append(i)
- range를 안쓴다면...
- 언어가 달라졌다고 사람의 뇌가 바뀌나보다. 파이썬으로 생각하려니까 자꾸 멈칫 멈칫하게 되고 코드가 잘 떠오르지 않는다.
- 조금 더 많이 풀어볼 필요가 있다고 느꼈다.
- 그리고 이 문제 또한 그래프의 가중치가 없기 때문에 BFS로 충분히 풀리는 문제이다.
- range로 모든 인덱스 탐색하는 형태를 쓰고 싶지 않은데 그렇다고 슬라이싱 또한 쓰고 싶지 않아서 굉장히 딜레마이다.
Code
# Baekjoon02660.py
import sys
input = sys.stdin.readline
INF = 0x3f3f3f3f
n = int(input())
adj_mat = [[INF for _ in range(n + 1)] for _ in range(n + 1)]
for i in range(1, n + 1):
adj_mat[i][i] = 0
a, b = map(int, input().split())
while not (a == -1 and b == -1):
adj_mat[a][b] = 1
adj_mat[b][a] = 1
a, b = map(int, input().split())
for k in range(1, n + 1):
for i in range(1, n + 1):
for j in range(1, n + 1):
adj_mat[i][j] = min(adj_mat[i][j], adj_mat[i][k] + adj_mat[k][j])
friend_list = [[] for _ in range(n + 1)]
for i in range(1, n + 1):
score = max(adj_mat[i][1:])
friend_list[score].append(i)
ans = 0
while ans < n and len(friend_list[ans]) == 0:
ans += 1
print(ans, len(friend_list[ans]))
print(*friend_list[ans])