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

#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;

#define MaxDistance 20000
#define None INT_MAX >> 1

int n, m, c, s, g;
vector<vector<int>> cost;
vector<vector<vector<int>>> dist;
vector<vector<vector<int>>> fee;

int main() {
  while (cin >> n >> m >> c >> s >> g, n | m | c | s | g) {
    s--;
    g--;
    dist = vector<vector<vector<int>>>(
        c, vector<vector<int>>(n, vector<int>(n, None)));
    for (int i = 0; i < m; i++) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      x--;
      y--;
      c--;
      dist[c][x][y] = dist[c][y][x] = min(dist[c][x][y], d);
    }
    cost = vector<vector<int>>(c, vector<int>(MaxDistance + 1));
    vector<int> p(c);
    for (int i = 0; i < c; i++)
      cin >> p[i];
    for (int company = 0; company < c; company++) {
      vector<int> q(p[company] + 1);
      vector<int> r(p[company]);
      q[0] = 0;
      q[p[company]] = MaxDistance;
      for (int i = 1; i < p[company]; i++)
        cin >> q[i];
      for (int i = 0; i < p[company]; i++)
        cin >> r[i];
      cost[company][0] = 0;
      for (int i = 0; i < p[company]; i++) {
        for (int j = q[i] + 1; j <= q[i + 1]; j++) {
          cost[company][j] = cost[company][j - 1] + r[i];
        }
      }
    }

    for (int company = 0; company < c; company++)
      for (int k = 0; k < n; k++)
        for (int i = 0; i < n; i++)
          for (int j = 0; j < n; j++)
            dist[company][i][j] = min(
                dist[company][i][j], dist[company][i][k] + dist[company][k][j]);
    fee = vector<vector<vector<int>>>(
        c, vector<vector<int>>(n, vector<int>(n, None)));
    for (int company = 0; company < c; company++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          if (dist[company][i][j] != None)
            fee[company][i][j] = cost[company][dist[company][i][j]];
    vector<vector<int>> minFee(n, vector<int>(n, None));
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        for (int company = 0; company < c; company++)
          minFee[i][j] = min(minFee[i][j], fee[company][i][j]);
    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          minFee[i][j] = min(minFee[i][j], minFee[i][k] + minFee[k][j]);
    cout << (minFee[s][g] == None ? -1 : minFee[s][g]) << endl;
  }
}

Error: MLE

Fixed submission:


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

#define MaxDistance 20000

class Edge {
public:
  int vertex, company, distance;
  Edge(int v, int c, int d) : vertex(v), company(c), distance(d) {}
};

class Node {
public:
  int vertex, company, distance, cost;
  Node(int v, int c, int d, int t)
      : vertex(v), company(c), distance(d), cost(t){};
  bool operator<(Node n) const {
    if (cost != n.cost)
      return cost < n.cost;
    if (distance != n.distance)
      return distance > n.distance;
    if (company != n.company)
      return company < n.company;
    return vertex < n.vertex;
  }
};

int n, m, c, s, g;
vector<vector<Edge>> edge;
vector<vector<int>> cost;

int Dijkstra() {
  vector<vector<vector<int>>> distance(
      n, vector<vector<int>>(c, vector<int>(MaxDistance, INT_MAX >> 1)));
  priority_queue<Node> q;
  int answer = -1;
  q.push(Node(s, c, 0, 0));
  while (!q.empty()) {
    Node now = q.top();
    q.pop();
    if (now.cost > MaxDistance)
      continue;
    if (answer != -1 && answer <= now.cost)
      continue;
    if (now.vertex == g)
      answer = (answer == -1 ? now.cost : min(answer, now.cost));
    for (int i = 0; i < edge[now.vertex].size(); i++) {
      Edge e = edge[now.vertex][i];
      if (now.vertex == e.vertex)
        continue;
      Node next = Node(e.vertex, e.company, e.distance, now.cost);
      if (now.company == e.company) {
        next.distance += now.distance;
        next.cost -= cost[e.company][now.distance];
        next.cost += cost[e.company][next.distance];
      } else {
        next.cost += cost[e.company][e.distance];
      }
      if (next.cost >= distance[next.vertex][next.company][next.distance])
        continue;
      distance[next.vertex][next.company][next.distance] = next.cost;
      q.push(next);
    }
  }
  return answer;
}

int main() {
  while (cin >> n >> m >> c >> s >> g, n | m | c | s | g) {
    s--;
    g--;

    edge = vector<vector<Edge>>(n, vector<Edge>());
    for (int i = 0; i < m; i++) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      x--;
      y--;
      c--;
      edge[x].push_back(Edge(y, c, d));
      edge[y].push_back(Edge(x, c, d));
    }

    cost = vector<vector<int>>(c, vector<int>(MaxDistance + 1));
    vector<int> p(c);
    for (int i = 0; i < c; i++)
      cin >> p[i];
    for (int company = 0; company < c; company++) {
      vector<int> q(p[company] + 1);
      vector<int> r(p[company]);
      q[0] = 0;
      q[p[company]] = MaxDistance;
      for (int i = 1; i < p[company]; i++)
        cin >> q[i];
      for (int i = 0; i < p[company]; i++)
        cin >> r[i];
      cost[company][0] = 0;
      for (int i = 0; i < p[company]; i++) {
        for (int j = q[i] + 1; j <= q[i + 1]; j++) {
          cost[company][j] = cost[company][j - 1] + r[i];
        }
      }
    }

    cout << Dijkstra() << endl;
  }
}