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

#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)

const int inf = INT_MAX / 3;
int riku[210][210];
int umi[210][210];
int dp[1010][210]; // [ツ妥ョツ配][ツ船ツづ個暗環置]

int main() {
  int n, m;
  int taku[1010];

  while (cin >> n >> m, n | m) {
    // init
    rep(i, 210) rep(j, 210) riku[i][j] = umi[i][j] = inf;
    rep(i, 210) riku[i][i] = umi[i][i] = 0;
    rep(i, 1010) rep(j, 210) dp[i][j] = inf;

    rep(i, m) {
      int a, b, c;
      char l;
      scanf(" %d %d %d %c ", &a, &b, &c, &l);
      a--, b--;
      if (l == 'S') {
        int d = min(umi[a][b], c);
        umi[a][b] = umi[b][a] = d;
      } else {
        int d = min(riku[a][b], c);
        riku[a][b] = riku[b][a] = d;
      }
    }
    int R;
    cin >> R;
    rep(i, R) {
      int r;
      cin >> r;
      r--;
      taku[i] = r;
    }

    // worshal
    rep(k, n) rep(i, n) rep(j, n) {
      if (riku[i][k] != inf && riku[k][j] != inf) {
        riku[i][j] = min(riku[i][j], riku[i][k] + riku[k][j]);
      }
      if (umi[i][k] != inf && umi[k][j] != inf) {
        umi[i][j] = min(umi[i][j], umi[i][k] + umi[k][j]);
      }
    }

    dp[1][taku[0]] = 0;
    REP(r, 1, R) {
      int v = taku[r - 1];
      int u = taku[r];
      rep(j, n) {
        if (riku[v][u] != inf)
          dp[r + 1][j] = min(dp[r + 1][j], dp[r][j] + riku[v][u]);
        if (riku[v][j] == inf)
          continue;
        rep(i, n) {
          if (umi[j][i] == inf || riku[i][u] == inf)
            continue;
          dp[r + 1][i] =
              min(dp[r + 1][i], dp[r][j] + riku[v][j] + umi[j][i] + riku[i][u]);
        }
      }
    }
    int ans = inf;
    rep(i, n) ans = min(ans, dp[R][i]);
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define DEB 0
#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)

class state {
public:
  int r, v, f, c;
  state(int _r, int _v, int _f, int _c) {
    r = _r;
    v = _v;
    f = _f;
    c = _c;
  }
  bool operator<(const state &a) const { return c > a.c; }
};
const int inf = INT_MAX;
int n, m;
int edge[2][210][210]; // 0 = umi, 1 = riku
int dp[1010][210][210]; // [ツ妥ョツ配ツ閉ィ][ツ個サツ催敖地][ツ船ツづ個暗環置]
int taku[1010];

int main() {
  while (cin >> n >> m, n | m) {
    // init
    rep(i, 210) rep(j, 210) edge[0][i][j] = edge[1][i][j] = inf;
    rep(i, 1001) rep(j, 210) rep(k, 210) dp[i][j][k] = inf;

    rep(i, m) {
      int a, b, c;
      char l;
      scanf(" %d %d %d %c ", &a, &b, &c, &l);
      a--;
      b--;
      if (l == 'S') {
        edge[0][a][b] = min(c, edge[0][a][b]);
        edge[0][b][a] = min(c, edge[0][b][a]);
      } else {
        edge[1][a][b] = min(c, edge[1][a][b]);
        edge[1][b][a] = min(c, edge[1][b][a]);
      }
    }

#if DEB
    puts("umi");
    rep(i, n) {
      rep(j, n) { printf("%d ", edge[0][i][j] == inf ? -1 : edge[0][i][j]); }
      puts("");
    }
    puts("rku");
    rep(i, n) {
      rep(j, n) { printf("%d ", edge[1][i][j] == inf ? -1 : edge[1][i][j]); }
      puts("");
    }
#endif

    int R;
    cin >> R;
    rep(i, R) {
      int a;
      scanf("%d ", &a);
      taku[i] = a - 1;
    }

    int ans = -1;
    priority_queue<state> q;
    if (taku[0] == 0) {
      dp[1][0][0] = 0;
      q.push(state(1, 0, 0, 0));
    } else {
      dp[0][0][0] = 0;
      q.push(state(0, 0, 0, 0));
    }

    while (!q.empty()) {
      state s = q.top();
      q.pop();
#if DEB
      printf("r:%d, v:%d, f:%d, c:%d\\n", s.r, s.v, s.f, s.c);
#endif

      if (s.r == R) {
        ans = s.c;
        break;
      }
      rep(i, n) {
        int ne = s.r;
        if (i == taku[s.r])
          ne++;

        // printf("i:%d   s.v:%d  s.f:%d,  edge:%d\\n",i,s.v, s.f,
        // edge[0][s.v][i]);

        if (edge[1][s.v][i] != inf) { // riku
          if (dp[ne][i][s.f] > edge[1][s.v][i] + s.c) {
            int d = edge[1][s.v][i] + s.c;
            dp[ne][i][s.f] = d;
#if DEB
            printf("riku :: ne:%d i:%d , f:%d, d:%d\\n", ne, i, s.f, d);
#endif
            q.push(state(ne, i, s.f, d));
          }
        }
        if (s.v == s.f && edge[0][s.v][i] != inf) { // umi
          if (dp[ne][i][i] > edge[0][s.v][i] + s.c) {
            int d = edge[0][s.v][i] + s.c;
            dp[ne][i][i] = d;
#if DEB
            printf("umi :: ne:%d i:%d , f:%d, d:%d\\n", ne, i, i, d);
#endif
            q.push(state(ne, i, i, d));
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}