플로이드 워셜 알고리즘

2025. 9. 10. 12:21·알고리즘 정리
반응형

플로이드 워셜 알고리즘이란?

가중치가 있는 방향/무방향 그래프에서 모든 정점 쌍 사이의 최단 거리를 한번에 구하는 DP 기반 알고리즘

음수 가중치 간선은 허용하지만, 음수 사이클이 있으면 최단거리가 정의되지 않는다.

시간 공간 복잡도

시간 : O(N^3)

공간 : O(N^2)

핵심 아이디어

dist[i][j]=min(dist[i][j], dist[i][k]+dist[k][j])

 

해석 : i → j 까지 가는 가장 짧은 값을 출력

i → k → j 가 가능하다면 해당 값으로 값을 대체

❗반복문의 순서가 중요하다 k → i → j

중간 정점으로 1..k만 허용 하는 부분 문제를 누적해야 하므로 이 순서가 무조건 보장 되어야한다.

사용 판단 기준

  1. N이 중간 규모 대략 N≤500 이고 모든 쌍의 거리 도달성을 한번에 알고 싶을 때,
  2. 그래프가 간선이 많아 다익스트라 알고리즘을 N번 돌리는 이점이 적을 때,

반대로 노드가 500 이상이고 그래프간의 간선이 적으면 다익스트라 * N 알고리즘 이나 존슨 알고리즘이 더 좋다.

풀이 방법

import java.io.*;
import java.util.*;

public class FloydWarshall {
    static final long INF = (long)1e15; // 합 연산 대비 넉넉한 INF (int 오버플로 방지)
    static int N, M;
    static long[][] dist;
    static int[][] next; // 경로 복원용 (i->j 최단경로에서 i 다음 노드)

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        N = Integer.parseInt(br.readLine().trim());
        M = Integer.parseInt(br.readLine().trim());

        dist = new long[N+1][N+1];
        next = new int[N+1][N+1];

        // 1) 초기화
        for (int i = 1; i <= N; i++) {
            Arrays.fill(dist[i], INF);
            dist[i][i] = 0;
        }
        
        // 2) 간선 입력 (다중 간선 -> 더 작은 가중치만)
        for (int e = 0; e < M; e++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            long w = Long.parseLong(st.nextToken());
            if (w < dist[a][b]) {
                dist[a][b] = w;
                next[a][b] = b; // 바로 가는 간선이면 경로복원 시작점
            }
        }
        
        // 3) 핵심 3중 루프 (k -> i -> j)
        for (int k = 1; k <= N; k++) {
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= N; j++) {
                    long nd = dist[i][k] + dist[k][j];
                    if (nd < dist[i][j]) {
                        dist[i][j] = nd;
                        next[i][j] = next[i][k]; // 경로복원 포인트
                    }
                }
            }
        }
        // 4) 음수 사이클 검사: dist[i][i] < 0 이면 i에서 i로 음수사이클
        boolean hasNegCycle = false;
        for (int v = 1; v <= N; v++) {
            if (dist[v][v] < 0) { hasNegCycle = true; break; }
        }

        // 출력 or 사용 예시
        System.out.println("hasNegCycle = " + hasNegCycle);
        // 예: 1->5 최단거리와 경로
        int s = 1, t = 5;
        if (dist[s][t] >= INF/2) {
            System.out.println("unreachable");
        } else {
            System.out.println("dist = " + dist[s][t]);
            System.out.println("path = " + getPath(s, t));
        }
    }
    
    // 경로 복원 (next 배열 사용)
    static List<Integer> getPath(int u, int v) {
        if (next[u][v] == 0) return Collections.emptyList();
        List<Integer> path = new ArrayList<>();
        path.add(u);
        while (u != v) {
            u = next[u][v];
            if (u == 0) return Collections.emptyList(); // 방어적
            path.add(u);
        }
        return path;
    }
}

마무리 요약

  • 플로이드–워셜은 간단한 코드로 모든 쌍 최단거리/도달성/경로를 한 번에 해결한다.
  • N이 중간 규모(500), 여러 질의가 있거나 행렬 변형 응용이 필요할 때 사용
반응형

'알고리즘 정리' 카테고리의 다른 글

A-star 알고리즘  (0) 2025.10.12
다익스트라 알고리즘 (Dijkstra’s Algorithm) 개념 정리  (0) 2025.10.02
0-1 knapsack 문제정리  (0) 2025.09.14
투포인터 알고리즘 (Two Pointer Algorithm)  (0) 2025.09.11
최장 증가 부분 수열 (LIS)  (0) 2025.09.09
'알고리즘 정리' 카테고리의 다른 글
  • 다익스트라 알고리즘 (Dijkstra’s Algorithm) 개념 정리
  • 0-1 knapsack 문제정리
  • 투포인터 알고리즘 (Two Pointer Algorithm)
  • 최장 증가 부분 수열 (LIS)
WHITE_FROST
WHITE_FROST
개발공부리뷰블로그
    반응형
  • WHITE_FROST
    하얀하얀IT
    WHITE_FROST
  • 전체
    오늘
    어제
    • 분류 전체보기 (119)
      • Stack (43)
        • Next.js (7)
        • React (12)
        • React-Native (15)
        • TypeScript (0)
        • Python (2)
        • JavaScript (2)
        • Android (1)
        • DB (2)
        • JAVA (1)
      • Obsidian (1)
      • AI (3)
      • AI Tools (0)
      • Tools (0)
      • Mac (0)
      • Error (7)
      • 알고리즘 정리 (6)
      • 알고리즘 문제풀이 (46)
      • 공부일상 (4)
      • 개발 도구 & 라이브러리 (0)
      • 정보처리기사 (0)
      • 기타 (6)
      • Tip (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    react-native
    ios
    리액트네이티브
    mongodb cloud
    D2
    mongoDB Atlas
    reactnative
    hooks
    티스토리챌린지
    알고리즘
    boj
    Python
    SWEA
    백준
    React Hooks
    error
    react-native-maps
    java
    Expo
    javascript
    코테준비
    ReactHook
    코테
    오블완
    코딩테스트
    react
    Next.js
    d1
    프로그래머스
    React-Native cli
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
WHITE_FROST
플로이드 워셜 알고리즘
상단으로

티스토리툴바