플로이드-워셜 예제 - 3

문제 분석

  • BFS 탐색 알고리즘을 이용해도 해결할 수 있는 문제이다.

  • 유저의 최대 수가 100으로 매우 작기 때문에 플로이드-워셜 알고리즘으로도 해결할 수 있다.

  • 이를 위해서는 몇 가지 아이디어가 필요하다.

    • 사람들이 직접적인 친구 관계를 맺은 상태를 비용 1로 계산한다. 가중치를 1로 정한 후 인접 행렬에 저장한다.

    • 플로이드-워셜은 모든 쌍과 관련된 최단 경로이므로 한 row값은 애 row의 index값에서 다른 모든 노드와 관련된 최단 경로를 나타낸다고 볼 수 있다. 즉, i번째 row의 합이 i번째 사람의 케빈 베이컨의 수가 된다는 뜻이다.

손으로 풀어보기

  1. 인접 행렬을 생성한 후, 자기 자신이면(i==j)0, 아니면 큰 수로 인접 행렬의 값을 초기화한다. 그리고 주어진 친구 관계 정보를 인접 행렬에 저장한다. i와 j가 친구라면 distance[i][j]distance[j][i]를 1로 저장한다.

  2. 플로이드-워셜 알고리즘을 수행해 3중 for 문으로 모든 중간 경로를 탐색한다.

  • Math.min(D[S][E], D[S][K] + D[K][E])

  1. 케빈 베이컨의 수(각 행의 합)를 비교해 가장 작은 수가 나온 행 번호를 정답으로 출력한다. 같은 수가 있을 때는 더 작은 행 번호를 출력한다.

슈도코드

n(노드 수) m(에지 수)
distance(인접 행렬) # 큰 수로 초기화

for n 반복:
    시작과 출발이 같으면 0
    
for m 반복:
    인접 행렬 데이터 저장
    양방향으로 가중치 1로 저장

for k n반복:
    for s n반복:
        for e n반복:
            distance[s][e]보다 distance[s][k] + distance[k][e]가 작으면 업데이트

min
ans

for i n반복:
    for j n반복:
        리스트의 행 합
    if min > 리스트의 행 합:
        min = 리스트의 행 합
        ans = i

ans 출력

코드 구현 - 파이썬

코드 구현 - 자바

Last updated