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

#include <algorithm>
#include <iostream>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;

#define EKI 100
#define KAISHA 20
#define DMAX 200
#define INF (1 << 29)

int n, m, c, s, g;
int d[EKI][EKI][KAISHA];
int p[KAISHA];
int q[KAISHA][50 + 1];
int r[KAISHA][50];

int cost[EKI][EKI];

int calc(int c, int dist) {
  int n = 0, res = 0, t;
  while (dist) {
    t = min(dist, q[c][n + 1] - q[c][n]);
    res += t * r[c][n];
    dist -= t;
    n++;
  }
  return res;
}
int main() {
  int t1, t2, t3, t4;
  while (cin >> n >> m >> c >> s >> g, n | m | c | s | g) {
    int ans = INF;
    fill_n((int *)cost, sizeof(cost) / sizeof(int), INF);
    fill_n((int *)d, EKI * EKI * KAISHA, INF);
    s--;
    g--;
    while (m--) {
      cin >> t1 >> t2 >> t3 >> t4;
      t1--;
      t2--;
      t4--;
      if (t3 < d[t1][t2][t4])
        d[t1][t2][t4] = d[t2][t1][t4] = t3;
    }
    for (int i = 0; i < c; i++)
      cin >> p[i];
    for (int i = 0; i < c; i++) {
      q[i][0] = 0;
      for (int j = 1; j < p[i]; j++)
        cin >> q[i][j];
      q[i][p[i]] = INF;
      for (int j = 0; j < p[i]; j++)
        cin >> r[i][j];
    }
    rep(l, c) { // ワーシャルフロイド
      rep(k, n) rep(i, n) rep(j, n) d[i][j][l] =
          min(d[i][j][l], d[i][k][l] + d[k][j][l]);
    }
    rep(i, n) rep(j, n) {
      int m = INF;
      rep(k, c) if (d[i][j][k] != INF) m = min(m, calc(k, d[i][j][k]));
      cost[i][j] = m;
    }
    rep(k, n) rep(i, n) rep(j, n) cost[i][j] =
        min(cost[i][j], cost[i][k] + cost[k][j]);
    ans = cost[s][g];
    cout << (ans != INF ? ans : -1) << endl;
  }
}

Error: MLE

Fixed submission:

// ICPC2012 D 鉄道乗り継ぎ
#include <algorithm>
#include <iostream>
#include <set>
using namespace std;

#define EKI 100
#define KAISHA 20
#define DMAX 200
#define INF (EKI * DMAX)

int n, m, c, s, g;
int d[EKI][EKI][KAISHA];
int p[KAISHA];
int q[KAISHA][50 + 1];
int r[KAISHA][50];

int dp[EKI][KAISHA][10001];

struct Node {
  int eki;
  int c;
  int dist;
  int pay;
  Node() {}
  Node(int a, int b, int c, int d) : eki(a), c(b), dist(c), pay(d) {}
  bool operator<(const Node &a) const { return pay < a.pay; }
};
int calc(int c, int dist) {
  int n = 0, res = 0, t;
  while (dist) {
    t = min(dist, q[c][n + 1] - q[c][n]);
    res += t * r[c][n];
    dist -= t;
    n++;
  }
  return res;
}
int main() {
  int t1, t2, t3, t4;
  multiset<Node> ms;
  Node a, b;
  while (cin >> n >> m >> c >> s >> g, n | m | c | s | g) {
    int ans = INF;
    fill_n((int *)dp, sizeof(dp) / sizeof(int), INF);
    fill_n((int *)d, EKI * EKI * KAISHA, INF);
    s--;
    g--;
    while (m--) {
      cin >> t1 >> t2 >> t3 >> t4;
      t1--;
      t2--;
      t4--;
      if (t3 < d[t1][t2][t4])
        d[t1][t2][t4] = d[t2][t1][t4] = t3;
    }
    for (int i = 0; i < c; i++)
      cin >> p[i];
    for (int i = 0; i < c; i++) {
      q[i][0] = 0;
      for (int j = 1; j < p[i]; j++)
        cin >> q[i][j];
      q[i][p[i]] = INF;
      for (int j = 0; j < p[i]; j++)
        cin >> r[i][j];
    }
    ms.clear();
    a = Node(s, -1, 0, 0);
    // dp[a.eki][a.c][a.dist]=a.pay;
    ms.insert(a);
    while (!ms.empty()) {
      a = *ms.begin();
      ms.erase(ms.begin());
      if (dp[a.eki][a.c][a.dist] < a.pay)
        continue;
      for (int i = 0; i < n; i++) {
        if (a.eki == i || s == i)
          continue;
        for (int j = 0; j < c; j++) {
          t1 = d[a.eki][i][j];
          if (t1 == INF)
            continue;
          b = Node(i, j, a.dist, a.pay);
          if (a.c == j) {
            b.dist += t1;
          } else {
            b.pay += calc(a.c, a.dist);
            b.dist = t1;
          }
          if (INF < b.dist)
            continue;
          if (b.pay < dp[b.eki][b.c][b.dist]) {
            dp[b.eki][b.c][b.dist] = b.pay;
            if (b.eki != g)
              ms.insert(b);
            t1 = calc(b.c, b.dist);
            if (g == b.eki && b.pay + t1 < ans)
              ans = b.pay + t1;
          }
        }
      }
    }
    cout << (ans != INF ? ans : -1) << endl;
  }
}