Problem p01317 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cstdio>
#include <iostream>
using namespace std;
const int MAX_N = 210;
const int MAX_T = 1005;
const int INF = 2 * MAX_N * MAX_T;
int N, M, R;
int sea[MAX_N][MAX_N];
int land[MAX_N][MAX_N];
const int MAX_R = 1005;
int O[MAX_R];
int dp[MAX_R][MAX_N];
void show(char s) {
  printf("\\n");
  if (s == 'L') {
    printf("Land\\n");
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        int n = land[i][j];
        if (n == INF)
          printf("INF ");
        else
          printf("%d ", n);
      }
      printf("\\n");
    }
  } else if (s == 'S') {
    printf("Sea\\n");
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        int n = sea[i][j];
        if (n == INF)
          printf("INF ");
        else
          printf("%d ", n);
      }
      printf("\\n");
    }
  }
}

int main(int argc, const char *argv[]) {
  while (true) {
    scanf("%d %d", &N, &M); // 町の番号は1~Nにする
    if (N == 0 && M == 0)
      break;
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        if (i == j) {
          sea[i][j] = land[i][j] = 0;
        } else {
          sea[i][j] = land[i][j] = INF;
        }
      }
    }
    for (int i = 0; i < M; i++) {
      int x, y, t;
      char s;
      scanf("%d %d %d %c", &x, &y, &t, &s);
      if (s == 'L') {
        land[x][y] = land[y][x] = t;
      } else if (s == 'S') {
        sea[x][y] = sea[y][x] = t;
      }
    }
    scanf("%d", &R);

    for (int i = 0; i < R; i++) {
      scanf("%d", &O[i]);
    }

    for (int k = 1; k <= N; k++) {
      for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
          land[i][j] = min(land[i][j], land[i][k] + land[k][j]);
          sea[i][j] = min(sea[i][j], sea[i][k] + sea[k][j]);
        }
      }
    }
    // 確認
    // show('L');
    // show('S');
    for (int i = 1; i <= N; i++)
      dp[0][i] = INF;
    dp[0][O[0]] = 0;

    for (int i = 1; i < R; i++) {
      for (int j = 1; j <= N; j++) {
        int minD = INF;
        for (int k = 1; k <= N; k++) {
          if (j == k) {
            minD = min(minD, dp[i - 1][j] + land[O[i - 1]][O[i]]);
          } else {
            minD = min(minD, dp[i - 1][k] + land[O[i - 1]][k] + sea[k][j] +
                                 land[j][O[i]]);
          }
          // printf("minD=%d\\n",minD);
        }
        dp[i][j] = minD;
      }
    }
    int ret = INF;
    for (int i = 1; i <= N; i++)
      ret = min(ret, dp[R - 1][i]);
    printf("%d\\n", ret);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
using namespace std;
const int MAX_N = 210;
const int MAX_T = 1005;
const int INF = 2 * MAX_N * MAX_T;
int N, M, R;
int sea[MAX_N][MAX_N];
int land[MAX_N][MAX_N];
const int MAX_R = 1005;
int O[MAX_R];
int dp[MAX_R][MAX_N];
void show(char s) {
  printf("\\n");
  if (s == 'L') {
    printf("Land\\n");
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        int n = land[i][j];
        if (n == INF)
          printf("INF ");
        else
          printf("%d ", n);
      }
      printf("\\n");
    }
  } else if (s == 'S') {
    printf("Sea\\n");
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        int n = sea[i][j];
        if (n == INF)
          printf("INF ");
        else
          printf("%d ", n);
      }
      printf("\\n");
    }
  }
}

int main(int argc, const char *argv[]) {
  while (true) {
    scanf("%d %d", &N, &M); // 町の番号は1~Nにする
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        if (i == j) {
          sea[i][j] = land[i][j] = 0;
        } else {
          sea[i][j] = land[i][j] = INF;
        }
      }
    }
    for (int i = 0; i < M; i++) {
      int x, y, t;
      char s;
      scanf("%d %d %d %c", &x, &y, &t, &s);
      if (s == 'L') {
        land[x][y] = land[y][x] = t;
      } else if (s == 'S') {
        sea[x][y] = sea[y][x] = t;
      }
    }
    scanf("%d", &R);

    for (int i = 0; i < R; i++) {
      scanf("%d", &O[i]);
    }

    for (int k = 1; k <= N; k++) {
      for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
          land[i][j] = min(land[i][j], land[i][k] + land[k][j]);
          sea[i][j] = min(sea[i][j], sea[i][k] + sea[k][j]);
        }
      }
    }
    // 確認
    // show('L');
    // show('S');
    for (int i = 1; i <= N; i++)
      dp[0][i] = INF;
    dp[0][O[0]] = 0;

    for (int i = 1; i < R; i++) {
      for (int j = 1; j <= N; j++) {
        int minD = INF;
        for (int k = 1; k <= N; k++) {
          if (j == k) {
            minD = min(minD, dp[i - 1][j] + land[O[i - 1]][O[i]]);
          } else {
            minD = min(minD, dp[i - 1][k] + land[O[i - 1]][k] + sea[k][j] +
                                 land[j][O[i]]);
          }
          // printf("minD=%d\\n",minD);
        }
        dp[i][j] = minD;
      }
    }
    int ret = INF;
    for (int i = 1; i <= N; i++)
      ret = min(ret, dp[R - 1][i]);
    printf("%d\\n", ret);
  }
  return 0;
}