아직 만들고 있는 페이지입니다.

이 페이지는 아직 만드는 중입니다. 보이는 내용은 바뀔 수 있습니다.

데이터 만들기 3

시간 제한1초메모리 제한128 MB

요약
최적화된 벨만-포드가 C번 이내의 반복으로 끝나지만 플로이드-워셜은 C번을 넘기는 SSSP 입력 파일을 정수 T개 이하로 만들되, 사전순으로 가장 작은 것을 출력하고 없으면 -1을 출력한다.
난이도

어려움10점 중 8점

유형
그래프, 최단 경로, 그리디, 구현
정답자
아직 제출이 없습니다

문제

프로그래밍 대회는 많다. 대회에 쓸 좋은 문제를 내는 일은 어렵고, 테스트 데이터를 만드는 일이 그중 가장 어렵다. 좋은 테스트 데이터는 문제의 의도에 맞게 짠 코드와 그렇지 않은 코드를 구별해야 한다. 대부분의 입력에서는 맞지만 특수한 입력에서만 틀리는 코드도 잡아야 한다.

이 문제는 최단 경로를 구하는 프로그램을 제출하는 문제가 아니다. 단일 출발 최단 경로(SSSP) 형식의 테스트 데이터 하나를 출력하는 문제이다.

상근이는 코드 A(OptimizedBellmanFord)와 코드 B(FloydWarshall)를 구별하는 데이터 XX를 만들어야 한다. 두 코드는 내부 반복 횟수를 counter에 담는다. counter가 CC를 넘으면 시간 초과이다. 힌트 소스의 리터럴 1000000은 이 문제에서 CC로 바꾼다.

데이터 XX는 다음을 모두 만족해야 한다.

  1. 코드 A가 XX를 처리할 때 시간 초과가 나면 안 된다.
  2. 코드 B가 XX를 처리할 때 시간 초과가 나야 한다.
  3. XX를 이루는 정수는 TT개 이하이다.

SSSP 입력 형식은 다음과 같다.

첫째 줄에 정점 수 VV가 나온다. 정점 번호는 00부터 V−1V-1까지이다. 다음 VV개 줄 중 ii번째 줄(0≤i<V0 \le i < V)에는 정점 ii에서 나가는 간선 수 nin_i가 나오고, 이어서 nin_i개의 쌍 jj ww가 나온다. jj는 도착 정점이고 ww는 가중치이다. 그다음 줄에 쿼리 수 QQ가 나온다. 다음 QQ개 줄에 sks_k와 tkt_k가 나온다.

데이터는 아래 조건을 모두 지켜야 한다.

  • 1≤V≤3001 \le V \le 300
  • nin_i는 00 이상의 정수이다
  • 0≤j<V0 \le j < V
  • ∣w∣<106|w| < 10^6
  • 0≤∑ni≤50000 \le \sum n_i \le 5000
  • 1≤Q≤101 \le Q \le 10
  • 0≤sk,tk<V0 \le s_k, t_k < V
  • 가중치 합이 음수인 사이클이 없다

조건을 만족하는 데이터가 여러 개이면, 정수 수열로 보았을 때 사전 순으로 가장 작은 것을 고른다. 앞에서부터 비교해 처음으로 다른 위치에서 더 작은 정수를 가진 수열이 앞선다. 한쪽이 다른 쪽의 접두사이면 짧은 쪽이 앞선다.

그런 데이터가 없으면 -1을 출력한다.

입력

첫째 줄에 정수 CC와 TT가 주어진다.

  • 0≤C≤1090 \le C \le 10^9
  • 1≤T≤1051 \le T \le 10^5

출력

조건을 만족하는 데이터가 없으면 한 줄에 -1을 출력한다.

있으면 SSSP 입력 형식 그대로 출력한다. 같은 줄의 정수는 공백 하나로 구분하고, 줄 끝에 공백을 두지 않는다.

첫째 줄에 VV를 출력한다. 다음 VV줄 가운데 ii번째 줄(ii는 00부터)에는 정점 ii의 나가는 간선 개수 nin_i를 쓰고, 이어서 nin_i개의 쌍 jj ww를 쓴다. 나가는 간선이 없으면 0만 쓴다. 그다음 줄에 QQ를 출력한다. 다음 QQ줄에 각 쿼리의 ss와 tt를 공백으로 구분해 출력한다.

힌트

코드 A는 최적화 벨만-포드이고, 코드 B는 플로이드-워셜이다. 아래 소스에서 리터럴 1000000은 입력 CC로 바꾼다. counter가 CC를 넘으면 시간 초과로 종료한다.

OptimizedBellmanFord:

#define INF 1000000000

int i, j, u, vv, w_u_vv, V, n, w, Q, counter, s, t;
int dist[1000];
int AdjList[1000][1000];
int weight[1000][1000];
int sz[1000];
int change;

int main() {
  scanf("%d", &V);
  for (i = 0; i < V; i++) {
    scanf("%d", &n);
    sz[i] = 0;
    while (n--) {
      scanf("%d %d", &j, &w);
      AdjList[i][sz[i]] = j;
      weight[i][sz[i]] = w;
      sz[i]++;
    }
  }
  counter = 0;
  scanf("%d", &Q);
  while (Q--) {
    scanf("%d %d", &s, &t);
    for (i = 0; i < V; i++) dist[i] = INF;
    dist[s] = 0;
    for (i = 0; i < V-1; i++) {
      change = 0;
      for (u = 0; u < V; u++)
        for (j = 0; j < sz[u]; j++) {
          counter++;
          if (counter > 1000000) {
            printf("TLE because iteration counter > 1000000\n");
            return 1;
          }
          vv = AdjList[u][j];
          w_u_vv = weight[u][j];
          if (dist[u] + w_u_vv < dist[vv]) {
            dist[vv] = dist[u] + w_u_vv;
            change = 1;
          }
        }
      if (!change)
        break;
    }
    printf("%d\n", dist[t]);
  }
  printf("The value of counter is: %d\n", counter);
  return 0;
}

FloydWarshall:

int i, j, k, V, n, w, M[300][300], counter, Q, s, t;

int main() {
  scanf("%d", &V);
  for (i = 0; i < V; i++)
    for (j = i+1; j < V; j++)
      M[i][j] = M[j][i] = 1000000000;
  for (i = 0; i < V; i++)
    M[i][i] = 0;
  for (i = 0; i < V; i++) {
    scanf("%d", &n);
    while (n--) {
      scanf("%d %d", &j, &w);
      if (w < M[i][j]) M[i][j] = w;
    }
  }
  counter = 0;
  for (k = 0; k < V; k++)
    for (i = 0; i < V; i++)
      for (j = 0; j < V; j++) {
        counter++;
        if (counter > 1000000) {
          printf("TLE because iteration counter > 1000000\n");
          return 1;
        }
        if (M[i][k] + M[k][j] < M[i][j]) M[i][j] = M[i][k] + M[k][j];
      }
  scanf("%d", &Q);
  while (Q--) {
    scanf("%d %d", &s, &t);
    printf("%d\n", M[s][t]);
  }
  printf("The value of counter is: %d\n", counter);
  return 0;
}

플로이드-워셜은 간선 수와 쿼리와 관계없이 V3V^3번 counter를 올린다. 최적화 벨만-포드는 한 라운드에서 갱신이 없으면 그 쿼리를 일찍 끝낸다.

예제3

  1. 예제 1

    입력
    1000000 100000
    
    예상 출력
    101
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    0 0
  2. 예제 2

    입력
    0 5
    
    예상 출력
    1
    0
    1
    0 0
  3. 예제 3

    입력
    8 6
    
    예상 출력
    -1