[C++] 플로이드-워셜(Floyd-warshall)

2023. 11. 16. 15:32·IT/알고리즘

 

 

 

플로이드-워셜(Floyd-warshall) 알고리즘은 모든 노드에 대해 그래프에서 최단 거리를 구하는 알고리즘이다. 이 알고리즘의 특징은 다음과 같다.

  • 음수 가중치가 있어도 수행할 수 있다.
  • 동적 계획법(Dynamic Programming) 원리를 따른다.
  • 시간 복잡도는 O(V ^ 3)으로 많이 느린 편에 속한다.

그래서 N이 1000개 이상인 경우에는 사용하기 어렵다.

 

 

 

 

 

플로이드-워셜 자료구조

먼저 그래프를 표현할 인접 행렬이 필요하다. 인접 행렬은 2개의 노드 인덱스와, 1개의 거리 요소로 구성되어 있다. 이 자료구조 하나로 플로이드-워셜 알고리즘을 구현할 수 있다.

 

 

 

 

 

플로이드-워셜 원리

플로이드-워셜의 핵심 원리는 A 노드에서 B 노드까지 최단 경로를 구했다고 가정했을 때 최단 경로 위에 K 노드가 존재한다면 그것을 이루는 부분 경로 역시 최단 경로라는 것이다.

 

예를 들어, 1 -> 5 최단 경로를 살펴보면 1 -> 4 최단 경로와 4 -> 5 최단 경로 역시 1 -> 5 최단 경로로 이뤄질 수 밖에 없다. 따라서 전체 최단 경로는 부분 경로의 최단 경로 조합으로 이뤄진다.

 

이 원리는 따라 다음과 같은 점화식을 만들 수 있다.

 

D[S][E] = min(D[S][E], D[S][K] + D[K][E])

 

 

 

 

먼저 인접 행렬을 초기화한다. 시작과 끝이 같은 D는 0으로, 다른 D는 Dummy로 초기화한다.

 

 

 

 

그 후 그래프를 인접 행렬에 저장한다.

 

 

 

 

3중 for loop을 통해 모든 경우를 탐색한다.

이제 원리에 맞춰 점화식을 코드로 구현하면 끝이다.

 

 

 

 

 

플로이드-워셜 코드 (백준 11404: 플로이드)

https://www.acmicpc.net/problem/11404

 

11404번: 플로이드

첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가

www.acmicpc.net

#include <iostream>
#include <vector>
#include <queue>

#define DUMMY 1e9+7

using namespace std;

int main()
{
	ios::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL);

	int N, M;
	cin >> N >> M;
	vector<vector<int>> matrix(N + 1, vector<int>(N + 1, DUMMY));

	for (int i = 1; i <= N; i++)
		matrix[i][i] = 0;

	for (int i = 0; i < M; i++)
	{
		int start, end, weight;
		cin >> start >> end >> weight;
		if (matrix[start][end] > weight)
			matrix[start][end] = weight;
	}

	for (int k = 1; k <= N; k++)
		for (int s = 1; s <= N; s++)
			for (int e = 1; e <= N; e++)
				matrix[s][e] = min(matrix[s][e], matrix[s][k] + matrix[k][e]);

	for (int s = 1; s <= N; s++)
	{
		for (int e = 1; e <= N; e++)
		{
			if (matrix[s][e] == DUMMY)
				matrix[s][e] = 0;
			cout << matrix[s][e] << ' ';
		}
		cout << '\n';
	}

	return 0;
}

 

 

 

'IT > 알고리즘' 카테고리의 다른 글

코딩 테스트에서 C++이 유리한 이유와 장점  (3) 2024.11.04
[C++] 최소 신장 트리(MST)  (0) 2023.11.16
[C++] 벨만-포드(Bellman-ford)  (1) 2023.11.16
[C++] 다익스트라(Dijkstra)  (1) 2023.11.16
[C++] 위상 정렬 (Topological Sort)  (0) 2023.11.15
'IT/알고리즘' 카테고리의 다른 글
  • 코딩 테스트에서 C++이 유리한 이유와 장점
  • [C++] 최소 신장 트리(MST)
  • [C++] 벨만-포드(Bellman-ford)
  • [C++] 다익스트라(Dijkstra)
게임을 제작하는 사람
게임을 제작하는 사람
안녕하세요, 게임 개발자 천냥입니다! 게임을 제작하는 개발자들에게 도움이 될만한 정보와 지식을 제공하는 블로그입니다 ;)
  • 게임을 제작하는 사람
    천냥의 게임 개발 일지
    게임을 제작하는 사람
  • 전체
    오늘
    어제
    • 분류 전체보기 (92) N
      • 유니티(Unity) (61) N
        • 콘텐츠 개발 (8) N
        • 툴 개발 (11)
        • 이슈 도감 (10)
        • 최적화 기법 (4)
        • 쉐이더 (3)
        • 포톤 (0)
        • 이론 정리 (15)
        • 유용한 패키지 정리 (3)
        • 패키지: Cinemachine 정리 (7)
      • C# (2)
      • IT (29)
        • 기술 정리 (2)
        • 알고리즘 (26)
        • Git (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    쉐이더
    패키지 버전 관리
    private upm
    custom package
    upm
    시네머신
    티스토리챌린지
    addressable
    verdaccio
    끝 없는 2d 맵
    upm 개발
    최적화
    oracle
    2d endless platform 구현
    코딩 테스트
    UI
    allin1spriteshader
    Unity
    Cinemachine
    유니티
    무한 플랫포머
    카메라
    커스텀 패키지
    C++
    Shader
    editor
    에디터
    openupm
    오블완
    코테
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
게임을 제작하는 사람
[C++] 플로이드-워셜(Floyd-warshall)
상단으로

티스토리툴바