개발/알고리즘
[프로그래머스] 부대복귀
개발자_티모
2023. 3. 23. 01:27
반응형
[문제 설명]
출발지에서 목적지까지 최단거리로 이동하는 경우를 구하는 문제입니다.
[해결 방법]
해당 문제는 BFS를 사용해 풀이하는 문제입니다. BFS를 이용한 빠른 길 찾기는 출발점으로부터 인접 노드들의 최단거리를 갱신하는 구조입니다. 이 때, 출발점이 하나이고 목적지는 x개일 수 있습니다.
주어진 예시를 보면 출발점은 x개인 반면에 도착점은 하나로 고정되어 있습니다. 즉, 도착점을 출발점으로 생각하여 인접 노드들의 최단거리 노드를 갱신하면 도착점에서부터 출발점까지의 최단거리를 구할 수 있습니다.
결과적으로 도착점을 출발점으로 탐색을 진행한다면 도착점에서 출발할 수 있는 모든 노드들의 최단거리를 구할 수 있습니다. sources 배열에 있는 노드들의 최단거리를 return하여 정답을 받을 수 있습니다.
[해결 과정에서 발생한 문제와 해결방법]
- 처음에는 다수의 출발점이기에 플로이드 와샬 알고리즘을 사용했지만 시간초과가 발생했습니다. 왜냐하면 플로이드 와샬의 시간복잡도는 O(n^3)인데 문제에서는 n이 10만이기 때문에 시간내에 통과할 수 없습니다.
- 초기 노드간의 연결을 표현하기 위해 N * N 배열을 사용했습니다. 이는 연결된 노드들의 거리를 갱신할 때 항상 N번을 반복해야해 제한시간 안에 문제를 해결할 수 없습니다. (기존의 방법 코드 참조).
- 하지만 개선된 방법의 경우 최악의 경우에만 N번의 반복문을 수행하기에 더 효율적이고, 제한된 시간안에 문제를 해결할 수 있습니다.
#기존의 방법
def find_next_node(start_point):
for next in range(n):
if map[start_point][next]:
calc_cost_to_next(start_point, next)
#개선된 방법
def find_next_node(start_point):
for next in map[start_point]:
calc_cost_to_next(start_point, next)
- 모든 노드들 사이의 거리가 1이기 때문에 BFS를 수행해야하는데 최단거리라는 키워드가 각인되어 데익스트라를 사용했습니다.
[정답 코드]
def solution(n, roads, sources, destination):
import heapq
answer = []
war_map = [ [] for _ in range(n + 1)]
for y, x in roads:
war_map[y].append(x)
war_map[x].append(y)
cost_map_of_point = [987654321] * (n + 1)
cost_arr = []
cost_map_of_point[destination] = 0
heapq.heappush(cost_arr, [0, destination])
while cost_arr:
cost, arrived_point = heapq.heappop(cost_arr)
if cost_map_of_point[arrived_point] < cost:
continue
for next in war_map[arrived_point]:
if cost + 1 < cost_map_of_point[next]:
heapq.heappush(cost_arr, [cost + 1, next])
cost_map_of_point[next] = cost + 1
for source in sources:
if cost_map_of_point[source] == 987654321:
cost_map_of_point[source] = -1
answer.append(cost_map_of_point[source])
return answer
if __name__ == "__main__":
print(solution(3, [[1, 2], [2, 3]], [2, 3], 1))
반응형