방향 가중치 그래프 G와 두 정점 s, t가 주어졌을 때, p(s,t)를 s에서 t까지 가는 최단 경로의 가중치 합으로 정의한다. s에서 t로 도달할 수 없으면 p(s,t)를 1,000,000,000으로 정의한다.
입력으로는 그래프 G와 Q개의 쿼리 (s1,t1),(s2,t2),…,(sQ,tQ)가 주어진다. 각 쿼리 k에 대해 p(sk,tk)를 출력하면 된다.
그래프에는 음의 가중치를 가진 간선이 있을 수 있으나, 가중치 합이 음수인 사이클은 존재하지 않는다.
입력은 두 개의 블록으로 이루어진다. 첫 번째 블록은 그래프 G의 인접 리스트를, 두 번째 블록은 쿼리를 나타낸다.
첫 번째 블록의 첫째 줄에는 정점의 개수 V가 주어진다. 정점은 0번부터 V−1번까지 번호가 매겨져 있다. 이어지는 V개의 줄에는 0번 정점부터 순서대로 각 정점의 정보가 주어진다. 각 줄의 첫 번째 수 ni는 정점 i에서 나가는 간선의 개수이며, 그 뒤로 ni개의 쌍 (j,w)가 이어진다. 각 쌍은 정점 i에서 정점 j로 향하는 가중치 w인 간선을 뜻한다.
두 번째 블록의 첫째 줄에는 쿼리의 개수 Q가 주어지고, 이어지는 Q개의 줄에 각각 sk와 tk가 주어진다.
한 줄에서 연속한 두 정수는 공백으로 구분된다. 입력은 다음 조건을 만족한다.
Q개의 줄을 출력한다. k번째 줄에는 p(sk,tk)의 값을 출력한다.
마지막 줄에는 아래 "힌트"에 정의된 알고리즘을 수행하는 동안 누적된 counter 변수의 최종 값을 다음 형식으로 출력한다.
The value of counter is: <counter>
각 쿼리 (sk,tk)는 아래의 큐 기반 벨만-포드(SPFA) 알고리즘으로 처리한다. counter 변수는 모든 쿼리에 걸쳐 값이 누적되며, 쿼리마다 초기화하지 않는다.
counter ← 0
입력에 주어진 순서대로 각 쿼리 (s, t)에 대해:
모든 정점 v에 대해 dist[v] ← ∞, 그리고 dist[s] ← 0
모든 정점 v에 대해 inQueue[v] ← false
FIFO 큐를 비우고 s를 넣는다
inQueue[s] ← true; counter ← counter + 1
큐가 빌 때까지 반복:
u ← 큐에서 하나 꺼낸다; inQueue[u] ← false
정점 u의 인접 리스트에 있는 각 간선 (u → v, 가중치 w)를 입력 순서대로:
만약 dist[u] + w < dist[v] 이면:
dist[v] ← dist[u] + w
만약 inQueue[v] = false 이면:
큐에 v를 넣는다; inQueue[v] ← true; counter ← counter + 1
p(s, t) = (dist[t] < ∞ 이면 dist[t], 그렇지 않으면 1,000,000,000)
정리하면 counter는 알고리즘 전체에서 정점이 큐에 삽입된 총 횟수이다. 각 쿼리 시작 시 출발점 s를 큐에 넣는 것도 1회로 센다.