플로이드 알고리즘에서 바깥 루프가 정점 N을 경유점으로 사용하지 않을 때, 두 버전의 최단 거리 값이 달라지는 순서쌍의 개수를 센다.
보통6최단 경로동적 계획법그래프면접 대비아직 제출이 없습니다시간 제한2초메모리 제한512 MB코딩 실력이 부족하다고 느끼던 지구이는 익명게시판에서 "백스페이스 키를 쓰지 않고 코딩하기를 추천합니다"라는 글을 읽었다. 글 맨 아래에는 효과를 보장할 수 없다는 내용이 아주 작은 글씨로 다섯 줄에 걸쳐 적혀 있었지만, 지구이는 한 번쯤 해 볼 만하다고 생각해 그대로 따라 했다.
지구이가 처음 도전한 문제는 정점이 N개인 그래프의 인접행렬 D가 주어질 때 모든 쌍의 최단거리를 구하는 것이었다. 지구이는 플로이드 알고리즘으로 풀려고 했지만 삼중 반복문의 첫 줄에서 오타를 냈다.
for (int k = 1; k < N; k++)
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
바깥 반복문의 조건이 k <= N이 아니라 k < N이어서 정점 N은 경유지로 한 번도 쓰이지 않는다. 백스페이스를 누르지 않기로 한 지구이는 이 오타를 지우지 못한 채 코드를 끝까지 썼고, 결국 틀렸다.
문제를 푼 뒤 지구이는 자신의 첫 코드가 얼마나 망가졌는지 확인하려고 한다. 인접행렬 D가 주어질 때, 오타가 난 코드가 구한 값과 올바른 플로이드가 구한 값이 서로 다른 순서쌍 (i,j)의 개수를 구하여라. i=j인 경우도 순서쌍에 포함한다.
두 코드 모두 위의 점화식만으로 값을 갱신한다. 인접행렬에 모든 순서쌍의 값이 들어 있으므로 무한대를 따로 두지 않는다.
첫째 줄에 정점의 개수 N (1≤N≤100)이 주어진다.
둘째 줄부터 N개의 줄에 인접행렬 D가 주어진다. i번째 줄의 j번째 수가 D(i,j)이다.
모든 i에 대해 D(i,i)=0이고, 모든 i, j에 대해 0≤D(i,j)≤10000이다.
첫째 줄에 두 코드의 결과가 다른 순서쌍 (i,j)의 개수를 출력한다.