데이터 만들기 1
시간 제한1초메모리 제한128 MB
플로이드-워셜은 10^6번을 넘겨 시간 초과가 나고 다익스트라는 그 이하로 통과하는 최단 경로 테스트 입력을 정수 개수가 최소가 되도록 하나 출력한다.
문제
프로그래밍 대회에 쓸 좋은 문제를 만드는 일은 어렵다. 그중에서도 테스트 데이터를 만드는 일이 가장 어렵다. 좋은 테스트 데이터는 문제의 의도에 맞게 짠 코드와 그렇지 않은 코드를 구별해야 한다. 대부분의 입력에서는 올바른 결과를 내지만 특별한 입력에서만 실패하는 코드도 찾아내야 한다.
이 문제는 최단 경로를 구하는 프로그램을 제출하는 문제가 아니다. 테스트 데이터를 출력하는 문제이다.
여러분은 가중 방향 그래프의 최단 경로 문제용 입력 데이터 를 하나 만들어야 한다. 는 아래 두 코드에 대해 다음 조건을 만족해야 한다.
- 수정 다익스트라가 를 처리할 때 시간 초과가 발생하면 안 된다.
- 플로이드-워셜이 를 처리할 때 시간 초과가 발생해야 한다.
데이터는 작을수록 좋다. 에 등장하는 정수는 최대 개이다.
두 코드는 연산 횟수를 세는 변수 를 둔다. 값이 을 넘으면 시간 초과이다.
는 다음 형식을 따른다.
첫째 줄에 정점 수 가 있다. 정점 번호는 부터 까지이다.
다음 개 줄 중 번째 줄은 정점 에서 나가는 간선을 나타낸다. 첫 수는 출차수 이고, 이어서 개의 쌍 가 온다. 각 쌍은 정점 에서 정점 로 가는 가중치 의 간선이다.
그다음 줄에 질의 수 가 있다. 다음 개 줄의 각 줄에는 질의의 시작점 와 도착점 가 있다.
데이터는 다음 제한을 지켜야 한다.
- 는 이상인 정수이다
- 어떤 질의의 시작점도 음수 사이클에 도달하지 않는다
도달할 수 없는 쌍의 최단 거리는 으로 둔다.
조건을 만족하는 데이터가 여러 개이면 정수 개수가 가장 적은 것을 고른다. 그것도 여러 개이면 출력에 등장하는 정수를 왼쪽부터 이은 수열을 사전순으로 비교해 가장 앞서는 것을 고른다.
입력
이 문제는 입력이 없다.
출력
위에서 고른 유일한 데이터를 다음처럼 출력한다.
첫째 줄에 를 출력한다.
다음 개 줄에 각 정점의 출차수와 간선 목록을 출력한다. 간선이 없으면 그 줄에는 만 출력한다.
그다음 줄에 를 출력한다.
다음 개 줄에 와 를 공백으로 구분해 출력한다.
힌트
플로이드-워셜은 인접 행렬 에서 다음을 수행한다.
counter = 0
for k = 0 to V-1:
for i = 0 to V-1:
for j = 0 to V-1:
counter = counter + 1
if counter > 1000000: TLE
M[i][j] = min(M[i][j], M[i][k] + M[k][j])
반복 횟수는 항상 이다. 간선 수와 질의 수에 의존하지 않는다.
수정 다익스트라는 각 질의 마다 다음을 수행한다. 처음에는 이고 나머지 정점의 거리는 무한대이다.
counter = 0
for each query (s, t):
dist[s] = 0
pq.push((0, s))
while pq is not empty:
counter = counter + 1
if counter > 1000000: TLE
(d, u) = pop(pq)
if d == dist[u]:
for each edge (u, v, w):
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
pq.push((dist[v], v))
우선순위 큐에서 꺼낸 횟수가 이다. 같은 정점이 여러 번 갱신되면 큐에 여러 번 들어갈 수 있다.