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

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

#define MAX_N 1020
#define INF 123456789

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>
    Q;

int L[MAX_N][MAX_N];
int S[MAX_N][MAX_N];
int LD[MAX_N][MAX_N];
int SD[MAX_N][MAX_N];
int DP[MAX_N][MAX_N];
int T[MAX_N], DIST[MAX_N];
int A, B, C, N, M, R, res;
char D;

void dijkstra(int v, int st) {
  for (int i = 0; i < MAX_N; i++) {
    DIST[i] = INF;
  }
  DIST[st] = 0;
  Q.push(make_pair(0, st));
  while (!Q.empty()) {
    pair<int, int> p = Q.top();
    Q.pop();
    for (int i = 1; i <= N; i++) {
      if (v == 1) {
        if (L[p.second][i] + p.first < DIST[i]) {
          DIST[i] = L[p.second][i] + p.first;
          Q.push(make_pair(DIST[i], i));
        }
      } else {
        if (S[p.second][i] + p.first < DIST[i]) {
          DIST[i] = S[p.second][i] + p.first;
          Q.push(make_pair(DIST[i], i));
        }
      }
    }
  }
}

int main() {
  while (true) {
    res = INF;
    for (int i = 0; i < MAX_N; i++) {
      for (int j = 0; j < MAX_N; j++) {
        L[i][j] = INF;
        S[i][j] = INF;
        LD[i][j] = INF;
        SD[i][j] = INF;
        DP[i][j] = INF;
      }
    }
    cin >> N >> M;
    if (N == 0 && M == 0) {
      break;
    }
    for (int i = 0; i < M; i++) {
      cin >> A >> B >> C >> D;
      if (D == 'L') {
        L[A][B] = C;
        L[B][A] = C;
      }
      if (D == 'S') {
        S[A][B] = C;
        S[B][A] = C;
      }
    }
    cin >> R;
    for (int i = 0; i < R; i++) {
      cin >> T[i];
    }
    for (int i = 1; i <= N; i++) {
      dijkstra(1, i);
      for (int j = 1; j <= N; j++) {
        LD[i][j] = DIST[j];
      }
    }
    for (int i = 1; i <= N; i++) {
      dijkstra(2, i);
      for (int j = 1; j <= N; j++) {
        SD[i][j] = DIST[j];
      }
    }
    DP[0][T[0]] = 0;
    for (int i = 0; i < R - 1; i++) {
      int ST = T[i], GO = T[i + 1];
      for (int j = 1; j <= N; j++) {
        DP[i + 1][j] = min(DP[i + 1][j], DP[i][j] + LD[ST][GO]);
        for (int k = 1; k <= N; k++) {
          DP[i + 1][k] =
              min(DP[i + 1][k], DP[i][j] + LD[ST][j] + SD[j][k] + LD[k][GO]);
        }
      }
    }
    for (int i = 1; i <= N; i++) {
      res = min(res, DP[R - 1][i]);
    }
    cout << res << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

#define WHITE 0
#define GRAY 1
#define BLACK 2
#define MAX_N 220
#define MAX_R 1020
#define INF 123456789

priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
               greater<tuple<int, int, int>>>
    Q;
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
               greater<tuple<int, int, int>>>
    Q2;
vector<tuple<int, int, int>> X[MAX_N];
string A4;
int N, M, R;
int A1, A2, A3;
int travel[MAX_R];
int DIST[MAX_N][MAX_N], DIST2[MAX_N];
int COLOR[MAX_N][MAX_N], COLOR2[MAX_N];
int PATH[MAX_N][MAX_N][MAX_N];
int DP[MAX_R][MAX_N];
int cnt, cnt2;

void dijkstra(int st) {
  while (!Q.empty()) {
    cnt++;
    tuple<int, int, int> tup = Q.top();
    int a1 = get<0>(tup);
    int a2 = get<1>(tup);
    int a3 = get<2>(tup);
    COLOR[a2][a3] = BLACK;
    Q.pop();

    for (int i = 0; i < X[a2].size(); i++) {
      int a4 = get<0>(X[a2][i]);
      int a5 = get<1>(X[a2][i]);
      int a6 = get<2>(X[a2][i]);

      if (a6 == 0) {
        int a7 = a1 + a5;
        if (DIST[a4][a3] > a7 && COLOR[a4][a3] != BLACK) {
          DIST[a4][a3] = a7;
          cnt++;
          COLOR[a4][a3] = GRAY;
          Q2.push(make_tuple(DIST[a4][a3], a4, a3));
        }
      }

      if (a6 == 1 && a2 == a3) {
        int a8 = a1 + a5;
        if (DIST[a4][a4] > a8 && COLOR[a4][a4] != BLACK) {
          DIST[a4][a4] = a8;
          cnt++;
          COLOR[a4][a4] = GRAY;
          Q2.push(make_tuple(DIST[a4][a4], a4, a4));
        }
      }
    }
    while (!Q2.empty()) {
      Q.push(Q2.top());
      Q2.pop();
    }
  }
}

void _memset() {
  N = 0;
  M = 0;
  R = 0;
  A1 = 0;
  A2 = 0;
  A3 = 0;
  A4 = "";
  for (int i = 0; i < MAX_N; i++) {
    for (int j = 0; j < MAX_N; j++) {
      DIST[i][j] = 0;
      DIST2[i] = 0;
      COLOR[i][j] = WHITE;
      COLOR2[i] = WHITE;
    }
  }
  for (int i = 0; i < MAX_N; i++) {
    for (int j = 0; j < MAX_N; j++) {
      for (int k = 0; k < MAX_N; k++) {
        PATH[i][j][k] = INF;
      }
    }
  }
  for (int i = 0; i < MAX_R; i++) {
    for (int j = 0; j < MAX_N; j++) {
      DP[i][j] = INF;
    }
  }
  for (int i = 0; i < MAX_R; i++) {
    travel[i] = 0;
  }
  for (int i = 0; i < MAX_N; i++) {
    X[i].clear();
  }
  while (!Q.empty()) {
    Q.pop();
  }
  while (!Q2.empty()) {
    Q2.pop();
  }
}

int main() {
  while (true) {
    _memset();
    cin >> N >> M;
    if (M >= 10000) {
      cnt2++;
    }
    if (cnt2 == 2) {
      break;
    }
    if (N == 0 && M == 0) {
      break;
    }
    for (int i = 0; i < M; i++) {
      cin >> A1 >> A2 >> A3 >> A4;
      if (A4 == "L") {
        X[A1].push_back(make_tuple(A2, A3, 0));
        X[A2].push_back(make_tuple(A1, A3, 0));
      }
      if (A4 == "S") {
        X[A1].push_back(make_tuple(A2, A3, 1));
        X[A2].push_back(make_tuple(A1, A3, 1));
      }
    }
    cin >> R;
    for (int i = 0; i < R; i++) {
      cin >> travel[i];
    }
    for (int i = 1; i <= N; i++) {
      for (int j = 0; j < MAX_N; j++) {
        for (int k = 0; k < MAX_N; k++) {
          DIST[j][k] = INF;
          COLOR[j][k] = WHITE;
        }
      }
      DIST[i][i] = 0;
      COLOR[i][i] = GRAY;
      Q.push(make_tuple(0, i, i));
      dijkstra(i);
      for (int j = 1; j <= N; j++) {
        for (int k = 1; k <= N; k++) {
          PATH[i][j][k] = DIST[j][k];
        }
      }
    }
    DP[0][travel[0]] = 0;
    for (int i = 0; i < R - 1; i++) {
      for (int j = 1; j <= N; j++) {
        int start = travel[i];
        int goal = travel[i + 1];
        if (start == j) {
          for (int k = 1; k <= N; k++) {
            DP[i + 1][k] = min(DP[i + 1][k], DP[i][j] + PATH[start][goal][k]);
          }
        } else {
          for (int k = 1; k <= N; k++) {
            DP[i + 1][j] = min(DP[i + 1][j], DP[i][j] + PATH[start][goal][j]);
            DP[i + 1][k] = min(DP[i + 1][k], DP[i][j] + PATH[start][j][start] +
                                                 PATH[j][goal][k]);
          }
        }
      }
    }
    int res = INF;
    for (int i = 1; i <= N; i++) {
      res = min(res, DP[R - 1][i]);
    }
    cout << res << endl;
  }
  return 0;
}