[백준] 11780 - 플로이드 2 (Python)

2024. 7. 7. 21:10·알고리즘 (PS)/BOJ
반응형

 

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

 

학교 알고리즘 분석 전공 수업시간에 배웠던 내용을 그대로 이용하면 쉽게 풀 수 있는 문제이다.

플로이드 알고리즘은 dp 를 이용하는 방법으로, node 개수가 많지 않을 때 사용할 수 있는 알고리즘이다.

시간복잡도는 node 개수가 n개 일 때, O(n³) 의 시간복잡도를 갖는다.

 

두 노드 a, b 사이의 최단거리 a, b 를 dist[a][b] 라고 할 때, 

 

dist[a][b] = min( for k in range 1 .. n, dist[a][k] + dist[k][b] )

 

로 정의할 수 있다.

 

글로 정리하면, 두 노드 사이의 최단 거리는 그 노드 사이를 k 번 노드를 경유해서 갈 때 더 짧다면 그 값으로 갱신하는 과정을 거치면 된다.

 

이제 이를 역추적해보자.

 

우선 두 노드 a, b 사이를 k 번째 노드가 지나야 한다고 할 때, 이 정보를 parent[a][b] = k 로 저장하면 된다.

그리고 이를 역추적할 때는 a, b 노드 사이를 가는 최단 경로는 a, k, b 로 보면 된다.

그리고 이 경로에 대해 다시 (a, k) 사이의 경로를 구하고, (k, b) 사이의 경로르 구하는 과정을 재귀적으로 반복하면 된다.

 

import sys
input = sys.stdin.readline

n = int(input())
m = int(input())
INF = 98765432120
dist = [[INF for _ in range(n+1)] for _ in range(n+1)]
for i in range(1, n+1):
    dist[i][i] = 0
for _ in range(m):
    a, b, c = map(int, input().split())
    dist[a][b] = min(dist[a][b], c)

parent = [[0 for _ in range(n+1)] for _ in range(n+1)]

for k in range(1, n+1):
    for i in range(1, n+1):
        for j in range(1, n+1):
            if dist[i][j] > dist[i][k] + dist[k][j]:
                dist[i][j] = dist[i][k] + dist[k][j]
                parent[i][j] = k

for i in range(1, n+1):
    for j in range(1, n+1):
        if dist[i][j] == INF:
            dist[i][j] = 0

for i in range(1, n+1):
    print(*dist[i][1:])


def get_path(_i, _j):
    if parent[_i][_j] == 0:
        return (_i, _j)
    interval = parent[_i][_j]
    path_front = get_path(_i, interval)
    path_back = get_path(interval, _j)
    return path_front + path_back[1:]


for i in range(1, n+1):
    for j in range(1, n+1):
        if dist[i][j] == 0:
            print(0)
        else:
            if parent[i][j] == 0:
                print(2, i, j)
            else:
                path = get_path(i, j)
                print(len(path), *path)

 

정답코드는 위와 같다.

 

get_path() 함수가 나오기 전에는 일반적인 플로이드 알고리즘이다.

차이점이 있다면 위에서 말한 것처럼 parent 배열을 채우는 코드가 한줄 추가되었다.

 

get_path 는 위에서 말한대로 재귀적으로 경로를 구하는 함수이다.

이때 (a, k) (k, b) 에 대해서 구했을 때, 앞/뒤 경로를 모두 포함해서 구하도록 했는데, k 가 중복되므로 중복되는 k를 제거하기 위해서 뒷 경로를 앞 경로에 붙일 때 맨 앞의 k를 빼고 붙이도록 했다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 (PS) > BOJ' 카테고리의 다른 글

[백준] 11003 - 최솟값 찾기 (Python, 우선순위 큐)  (0) 2024.07.23
[백준] 1600 - 말이 되고픈 원숭이 (Python)  (2) 2024.07.14
[백준] 21606 - 아침 산책 (Python)  (2) 2024.07.05
[백준] 2618 - 경찰차 (Python)  (3) 2024.06.29
[백준] 1450 - 냅색문제  (0) 2024.06.26
'알고리즘 (PS)/BOJ' 카테고리의 다른 글
  • [백준] 11003 - 최솟값 찾기 (Python, 우선순위 큐)
  • [백준] 1600 - 말이 되고픈 원숭이 (Python)
  • [백준] 21606 - 아침 산책 (Python)
  • [백준] 2618 - 경찰차 (Python)
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615)
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45)
        • 생각 정리 (23)
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[백준] 11780 - 플로이드 2 (Python)
상단으로

티스토리툴바