sol’s blog

다익스트라, 벨만 포드 알고리즘

sol-commits
sol-commitsMay 9, 2025
다익스트라, 벨만 포드  알고리즘
다익스트라벨만포드
사용양의 간선만 있을 때 최단 거리음의 간선이 있을 때 최단 거리
음수 사이클 탐지에도 사용
시간복잡도O(M log N)
- M: 간선, N: 노드
O(NM)
음수 가중치가 없다면,
다익스트라가 압도적으로
빠르기 때문에
다익스트라 사용
음수 가중치나 음수 사이클이
있을 때만 사용 권장

    다익스트라

    최단 거리 테이블을 조금씩 갱신하며 완성해내가는 알고리즘

    예시

            (2)
         1 ----- 2
         |     / |
       (5)  (1)  (3)
         | /     |
         3 ----- 4
           (2)
    - 노드: 1~4
    - 간선: (1-2, 2), (1-3, 5), (2-3, 1), (2-4, 3), (3-4, 2)
    
    🟢 초기 상태
    - distance: [inf, 0, inf, inf, inf]
    - pq: [(0, 1)]
    
    ▶ 1단계: 1번 노드 방문
    - 인접한 간선들:
        - (1→2, 2) → 거리 2 → 업데이트!
        - (1→3, 5) → 거리 5 → 업데이트!
    - distance: [inf, 0, 2, 5, inf]
    - pq: [(2, 2), (5, 3)]
    
    
    ▶ 2단계: 2번 노드 방문(거리 2)
    - 인접한 간선들:
        - (2→3, 1) → 현재 거리 = 2+1 = 3 → 기존 5보다 작다! 업데이트!
        - (2→4, 3) → 2+3 = 5 → 업데이트!
    - distance: [inf, 0, 2, 3, 5]
    - pq: [(3, 3), (5, 3), (5, 4)]
    
    ▶ 3단계: 3번 노드 방문(거리 3)
    - 인접한 간선들:
        - (3→4, 2) → 3+2 = 5 → 기존 5와 같음 → 업데이트 X
    - distance: [inf, 0, 2, 3, 5]
    - pq: [(5, 3), (5, 4)]
    
    ▶ 4단계: 3번 노드 재방문 -> 이미 짧은 거리로 방문했으므로 무시
    - pq: [(5, 4)]
    
    ▶ 5단계: 4번 노드 방문(거리 5) -> 인접 노드 없음 -> 끝
    markdown

    코드

    import heapq
    
    def dijkstra(start, graph, n):
    	distance = [float('inf')] * (n + 1)
    	distance[start] = 0
    	pq = [(0, start)]
    	
    	while pq:
    		dist, now = heapq.heappop(pq)
    		if distance[now] < dist:
    			continue
    		for nxt, cost in graph[now]:
    			new_cost = dist + cost
    			if new_cost < distnace[nxt]:
    				distance[nxt] = new_cost
    				heapq.heappush(pq, (new_cost, nxt))
    				
    	return distance
    python

    벨만 포드

    음의 간선을 포함한 그래프에서 최단거리 계산하는 알고리즘

    예시

    		 (2)
      1 ----- 2
      |     / |
    (5)  (1)  (3)
      | /     |
      3 ----- 4
         (2)
    

    - 노드: 1~4
    - 간선: (1-2, 2), (1-3, 5), (2-3, 1), (2-4, 3), (3-4, 2)
    
    🟢 초기 상태
    - distance: [0, inf, inf, inf, inf]
    
    ▶ 1회차(간선 1개로만 연결되어있는 노드 처리)
    노드 1까지 거리: 0
    노드 2까지 거리: 2
    노드 3까지 거리: 5
    노드 4까지 거리: inf
    
    ▶ 2회차(간선 2개로 연결되어있는 노드 처리)
    노드 1까지 거리: 0
    노드 2까지 거리: 2
    노드 3까지 거리: 3 (distance[2] + 1)
    노드 4까지 거리: 5 (distance[2] + 3)
    
    ▶ 3회차(간선 3개로 연결되어있는 노드 처리)
    노드 1까지 거리: 0
    노드 2까지 거리: 2
    노드 3까지 거리: 3 
    노드 4까지 거리: 5 
    markdown

    코드

    def bellman_ford(n, edges, start):
        dist = [float('inf')] * (n + 1)
        dist[start] = 0
    
        for i in range(n - 1):
            for u, v, cost in edges:
                if dist[u] + cost < dist[v]:
                    dist[v] = dist[u] + cost
    
        # 음수 사이클 확인
        for u, v, cost in edges:
            if dist[u] + cost < dist[v]:
                return None  # 음수 사이클 있음
    
        return dist
    python

    Tags