어이 젊은이! 모든 최단경로 다 구해서 내앞으로 가져와


플.와를 들어가기에 앞서

  • 제 블로그를 정독한 사람이라면, 앞서 배운 다익스트라 알고리즘을 통해서 특정 노드에서 부터 다른 노드까지의 최단 거리를 구할 수 있었습니다. 다익스트라의 시간 복잡도는
    • 간선의 갯수를 E, 정점의 개수를 V라고 했을 때 **O(ElogV)**의 시간 복잡도를 갖습니다.
  • 만약 우리가 다익스트라를 통해 모든 노드로부터 출발하는 최단 거리를 구했을 때는 O(V^2logV) 의 시간 복잡도를 갖게 됩니다.
  • 이러한 지식을 바탕으로 플로이드 와샬에 대해서 알아보겠습니다.

플로이드 와샬 알고리즘이란?

  • 플로이드 와샬 알고리즘은 정점 갯수가 V인 그래프에서 한 번에 모든 정점 사이의 최단 거리를 구해내는 알고리즘입니다.
  • 이렇게 까지만 들으면, 다른 최단거리 알고리즘 필요없이 이것만 쓰면 되는 것이 아니냐? 할텐데,,, 방법에 대해 들어보면,,, 아닌걸 아실껍니다.

floyyd

  • 플로이드 와샬 알고리즘은 정점 a, b에 대해 a 에서 b로 가는 최단 경로를 한 번에 구해야 합니다. 따라서 다음과 같은 준비물이 필요합니다.
    • 총 노드의 개수를 N 이라고 합시다.
    • a정점에서 b정점으로의 거리를 나타낼 수 있는 N^2 크기의 2차 배열 board를 만듭니다.
      • 대부분 자신에서 자신으로 가는 것은 cost가 0이므로 board[i][j] = 0 (if i == j)로 설정합니다.
      • 데이터를 받기 전까지 a에서 b로 가는 cost를 모르니, 나머지는 board[i][j] = INF 값으로 나올 수 없는 최대값으로 설정을 해줍니다.
      • 이렇게 한다면 사전에 준비해야될 내용들은 끝인 겁니다.
  • 플로이드 최단경로를 DP 형태로 정의하고 해결하는 방식을 씁니다.
    • a 에서 b까지 가는데 k라는 것을 지나칠 수 있다고 가정해봅시다. (k가 있을 수도, 없을 수도 있습니다)
    • 그렇다면 a -> b의 거리와 a -> k -> b의 거리중에 작은 값을 갖고 있는 것이 최단 거리가 될 것입니다.
    • 이러한 반복을 총 3개의 루프문을 통해서 확인을 해주면서 메모라이제이션을 해줄 것입니다.
      • if (board[a][b] > board[a][k] + board[k][b]) 라면 최소값을 바꿔줍니다.
  • 총 3개의 루프문을 통해서 확인해주므로, O(N^3)의 시간복잡도를 갖게 되고, 위에서 언급한 모든 노드에 대한 다익스트라의 O(N^2 * logN) 의 시간 복잡도와 비교했을 때 N^2개의 노드 이하까지는 다익스트라가 유리한 것을 알 수 있습니다.
  • 대부분 플로이드 와샬을 구하는 문제를 확인해보면 N 값이 백단위이기 때문에, 어떤것을 써도 상관이 없을 겁니다,,
  • 코드를 봐보도록 할게요!

플로이드 와샬 코드


관련된 문제

  • 백준 11404 플로이드

    • 문제 이름부터 플로이드여서 딱히 생각할 것은 없지만, 아래 조건들만 잘 생각해주면 무리없이 패스

      • 시작 도시와 도착 도시를 연결하는 노선은 하나가 아닐 수 있다.

      • 만약, i에서 j로 갈 수 없는 경우에는 그 자리에 0을 출력한다.

  • 백준 11403 경로 찾기

    • 이것은 위의 문제와 입력이 다르게 주어진다. 즉 더 쉽다.
  • 백준 2610 회의준비

    • 대표를 뽑아야 하는데, 위원회 중에서 다른 정점들과의 최단거리 중에서 최대값이 가장 작은 사람을 뽑아야 한다.
    • 딕셔너리를 사용해보는 것은 어떨까?