이 영역을 누르면 첫 페이지로 이동
Arc 블로그의 첫 페이지로 이동

Arc

페이지 맨 위로 올라가기

Arc

[Algorithm] 벨만-포드 알고리즘(Bellman-Ford Algorithm)

  • 2023.03.30 00:54
  • Algorithm/Algorithm
글 작성자: SeoArc

벨만-포드 알고리즘(Bellman-Ford Algorithm)?

벨만-포드 알고리즘은 한 정점에서 다른 정점까지의 최단 거리를 구하는 알고리즘이다.

 

특징

벨만-포드 알고리즘의 시간 복잡도는 O(VE)로, O((V+E)logV)인 다익스트라보다 시간 복잡도가 더 크지만, 다익스트라는 가중치가 음수인 경우에는 사용할 수 없다.

반면, 벨만-포드 알고리즘은 가중치가 음수인 경우에도 사용할 수 있기 때문에 음수인 가중치가 존재한다면 벨만-포드 알고리즘을 사용할 필요가 있다.

 

구현

P[A][B]는 A와 B사이의 거리라고 가정한다.

  1. 출발점으로부터 최단거리를 저장할 배열 d[v]를 만들고, 출발 노드에는 0을, 출발점을 제외한 다른 노드들에는 매우 큰 값 INF를 채워 넣는다. 실무에서는 보통 d의 원소 타입에 대한 최대값으로 설정한다.
  2. 모든 간선에 대해, d[A] + P[A][B]와 d[B]의 값을 비교한다. INF와 비교할 경우 무조건 전자가 작다.
  3. 만약 d[A] + P[A][B]의 값이 더 작다면, 즉 더 짧은 경로라면, d[B]의 값을 이 값으로 갱신시킨다.
  4. 3 ~ 5의 과정을 v-1번 반복한다.
    • 음수 사이클을 확인하고 싶다면 v번 반복하여 v번째 반복 시 갱신할 값이 있는지 체크한다.

 

다음 코드는 [Baekjoon] 11657: 타임머신을 기준으로 작성하였다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Q11657 {

    private static int n;
    private static int m;
    private static List<int[]> edges;
    private static long[] weights;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        edges = new ArrayList<>();
        String[] nm = br.readLine().split(" ");
        n = Integer.parseInt(nm[0]);
        m = Integer.parseInt(nm[1]);
        weights = new long[n + 1];
        Arrays.fill(weights, Integer.MAX_VALUE);
        weights[1] = 0;

        for (int i = 0; i < m; i++) {
            String[] abc = br.readLine().split(" ");
            int a = Integer.parseInt(abc[0]);
            int b = Integer.parseInt(abc[1]);
            int c = Integer.parseInt(abc[2]);
            edges.add(new int[]{a, b, c});
        }

        for (int i = 1; i <= n; i++) {
            for (int[] edge : edges) {
                int startNode = edge[0];
                int nextNode = edge[1];
                int nextWeight = edge[2];

                if (weights[startNode] != Integer.MAX_VALUE && weights[nextNode] > weights[startNode] + nextWeight) {
                    weights[nextNode] = weights[startNode] + nextWeight;
                    if (i == n) {
                        System.out.println(-1);
                        return;
                    }
                }
            }
        }

        for (int i = 2; i <= n; i++) {
            if (weights[i] == Integer.MAX_VALUE) {
                sb.append(-1).append("\n");
                continue;
            }
            sb.append(weights[i]).append("\n");
        }

        System.out.print(sb);
    }
}
저작자표시 (새창열림)

'Algorithm > Algorithm' 카테고리의 다른 글

[Algorithm] 외판원 순회 문제(Traveling Salesman Problem)  (0) 2023.04.06
[Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)  (0) 2023.04.04
[Algorithm] 페르마의 소정리  (1) 2023.03.18
[Algorithm] 플로이드-워셜(Floyd-Warshall)  (0) 2023.03.12
[Algorithm] 상계/하계(Upper Bound/Lower Bound)  (1) 2023.03.11

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Algorithm] 외판원 순회 문제(Traveling Salesman Problem)

    [Algorithm] 외판원 순회 문제(Traveling Salesman Problem)

    2023.04.06
  • [Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)

    [Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)

    2023.04.04
  • [Algorithm] 페르마의 소정리

    [Algorithm] 페르마의 소정리

    2023.03.18
  • [Algorithm] 플로이드-워셜(Floyd-Warshall)

    [Algorithm] 플로이드-워셜(Floyd-Warshall)

    2023.03.12
다른 글 더 둘러보기

정보

Arc 블로그의 첫 페이지로 이동

Arc

  • Arc의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록

카테고리

  • 분류 전체보기 (109)
    • Language (28)
      • C++ (0)
      • C# (0)
      • Java (28)
    • Algorithm (47)
      • Algorithm (15)
      • Data Structure (6)
      • PS (26)
    • Computer Science (22)
      • Design Pattern (1)
      • Network (14)
      • OS (7)
    • Game (0)
      • Unity (0)
    • Backend (5)
      • Spring (3)
      • JPA (2)
    • DB (0)
      • SQL (0)
    • DevOps (1)
      • AWS (0)
      • Docker (2)
      • Jenkins (0)
      • Nginx (0)
    • Software Engineering (4)
      • OOP (4)
    • AI (0)
      • Machine Learning (0)
    • Others (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 알고리즘
  • 네트워크
  • 그래프
  • 자바
  • algorithm
  • graph
  • java
  • network

나의 외부 링크

정보

SeoArc의 Arc

Arc

SeoArc

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © SeoArc. Designed by Fraccino.

티스토리툴바