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

// ------ Includes ------ //

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

// ------ Variable Definition ------ //

#define INF (1 << 26)

#define MAX_N 200
#define MAX_R 1000

int N, M, R, X, Y, T;
char SL;

int S[MAX_N][MAX_N], L[MAX_N][MAX_N]; // Graph

int Short_S[MAX_N][MAX_N], Short_L[MAX_N][MAX_N]; // Shortest_Path

int Z[MAX_R + 1], dp[MAX_R + 1][MAX_N]; // dp[i][j] --> i = town, j = ship

// ------ Shortest Path Function ------ //

void Shortest(int start, string mode) {
  int D[MAX_N];
  for (int i = 0; i < MAX_N; i++) {
    D[i] = INF;
  }

  bool P[MAX_N];
  for (int i = 0; i < MAX_N; i++) {
    P[i] = false;
  }

  D[start] = 0;

  while (true) {
    int v = -1;

    for (int i = 0; i < N; i++) {
      if (P[i] == false) {
        if (v == -1) {
          v = i;
        } else if (D[i] < D[v]) {
          v = i;
        }
      }
    }

    if (v == -1) {
      break;
    }

    P[v] = true;

    for (int i = 0; i < N; i++) {
      if (mode == "Land") {
        D[i] = min(D[i], D[v] + L[v][i]);
      } else {
        D[i] = min(D[i], D[v] + S[v][i]);
      }
    }
  }

  for (int i = 0; i < N; i++) {
    if (mode == "Sea") {
      Short_S[start][i] = D[i];
    } else {
      Short_L[start][i] = D[i];
    }
  }
}

int main() {
  // ------ Input, Graph Construction ------ //

  while (true) {
    cin >> N >> M;

    if (N == 0 && M == 0) {
      break;
    }

    for (int i = 0; i < MAX_N; i++) {
      for (int j = 0; j < MAX_N; j++) {
        S[i][j] = INF;
        L[i][j] = INF;
      }
    }

    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        Short_L[i][j] = 0;
        Short_S[i][j] = 0;
      }
    }

    for (int i = 0; i < M; i++) {
      cin >> X >> Y >> T >> SL;

      switch (SL) {
      case 'S':
        S[X - 1][Y - 1] = T;
        S[Y - 1][X - 1] = T;
        break;
      case 'L':
        L[X - 1][Y - 1] = T;
        L[Y - 1][X - 1] = T;
        break;
      }
    }

    cin >> R;

    for (int i = 1; i <= R; i++) {
      cin >> Z[i];
      Z[i] -= 1; // 0 - indexed
    }

    Z[0] = Z[1];

    // ------ Shortest Path ------ //

    for (int i = 0; i < N; i++) {
      Shortest(i, "Land");
      Shortest(i, "Sea");
    }

    for (int i = 0; i <= R; i++) {
      for (int j = 0; j < N; j++) {
        dp[i][j] = INF;
      }
    }

    dp[0][Z[0]] = 0;

    for (int i = 1; i <= R; i++) {
      int Land_Only = Short_L[Z[i - 1]][Z[i]];

      for (int k = 0; k < N; k++) {
        dp[i][k] = min(dp[i - 1][k] + Land_Only, dp[i][k]);
      }

      for (int j = 0; j < N; j++) {
        if (dp[i - 1][j] != INF) {
          int Land_1 = Short_L[Z[i - 1]][j];

          for (int k = 0; k < N; k++) {
            int Sea = Short_S[j][k];

            int Land_2 = Short_L[k][Z[i]];

            dp[i][k] = min(dp[i][k], dp[i - 1][j] + Land_1 + Sea + Land_2);
          }
        }
      }
    }

    int Answer = INF;

    for (int i = 0; i < N; i++) {
      Answer = min(Answer, dp[R][i]);
    }

    cout << Answer << endl;
  }

  return 0;
}

// Time : O ( R * N ^ 2 + N ^ 3 )

Error: TLE

Fixed submission:

// ------ Includes ------ //

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

// ------ Variable Definition ------ //

#define INF (1 << 26)

#define MAX_N 200
#define MAX_R 1000

int N, M, R, X, Y, T;
char SL;

int S[MAX_N][MAX_N], L[MAX_N][MAX_N]; // Graph

int Z[MAX_R + 1], dp[MAX_R + 1][MAX_N]; // dp[i][j] --> i = town, j = ship

// ------ Shortest Path Function ------ //

int Shortest(int start, int goal, string mode) {
  int D[MAX_N];
  for (int i = 0; i < MAX_N; i++) {
    D[i] = INF;
  }

  bool P[MAX_N];
  for (int i = 0; i < MAX_N; i++) {
    P[i] = false;
  }

  D[start] = 0;

  while (true) {
    int v = -1;

    for (int i = 0; i < N; i++) {
      if (P[i] == false) {
        if (v == -1) {
          v = i;
        } else if (D[i] < D[v]) {
          v = i;
        }
      }
    }

    if (v == -1) {
      break;
    }

    P[v] = true;

    for (int i = 0; i < N; i++) {
      if (mode == "Land") {
        D[i] = min(D[i], D[v] + L[v][i]);
      } else {
        D[i] = min(D[i], D[v] + S[v][i]);
      }
    }
  }

  return D[goal];
}

int main() {
  // ------ Input, Graph Construction ------ //

  while (true) {
    cin >> N >> M;

    if (N == 0 && M == 0) {
      break;
    }

    for (int i = 0; i < M; i++) {
      cin >> X >> Y >> T >> SL;

      switch (SL) {
      case 'S':
        S[X - 1][Y - 1] = T;
        S[Y - 1][X - 1] = T;
        break;
      case 'L':
        L[X - 1][Y - 1] = T;
        L[Y - 1][X - 1] = T;
        break;
      }
    }

    cin >> R;

    for (int i = 1; i <= R; i++) {
      cin >> Z[i];
      Z[i] -= 1; // 0 - indexed
    }

    Z[0] = Z[1];

    // ------ Shortest Path ------ //

    for (int i = 0; i <= R; i++) {
      for (int j = 0; j < N; j++) {
        dp[i][j] = INF;
      }
    }

    dp[0][Z[0]] = 0;

    for (int i = 1; i <= R; i++) {
      int Land_Only = Shortest(Z[i - 1], Z[i], "Land");

      for (int k = 0; k < N; k++) {
        dp[i][k] = min(dp[i - 1][k] + Land_Only, dp[i][k]);
      }

      for (int j = 0; j < N; j++) {
        if (dp[i - 1][j] != INF) {
          int Land_1 = Shortest(Z[i - 1], j, "Land");

          for (int k = 0; k < N; k++) {
            int Sea = Shortest(j, k, "Sea");

            int Land_2 = Shortest(k, Z[i], "Land");

            dp[i][k] = min(dp[i][k], dp[i - 1][j] + Land_1 + Sea + Land_2);
          }
        }
      }
    }

    int Answer = INF;

    for (int i = 0; i < N; i++) {
      Answer = min(Answer, dp[R][i]);
    }

    cout << Answer << endl;

    // ------ Variable Value ------ //

    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        S[i][j] = INF;
        L[i][j] = INF;
      }
    }
  }

  return 0;
}