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

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
const int INF = 2000000000;

template <typename T> class fixed_vector {
  size_t m_size;
  T *m_data;

public:
  typedef T *iterator;

  explicit fixed_vector(size_t size = 0, const T &x = T()) : m_size(size) {
    m_data = new T[size];
    fill(m_data, m_data + size, x);
  }
  fixed_vector(const fixed_vector<T> &v) : m_size(v.m_size) {
    m_data = new T[m_size];
    copy(v.m_data, v.m_data + m_size, m_data);
  }
  ~fixed_vector() { delete[] m_data; }

  fixed_vector<T> &operator=(const fixed_vector<T> &v) {
    delete[] m_data;
    m_size = v.m_size;
    m_data = new T[m_size];
    copy(v.m_data, v.m_data + m_size, m_data);
  }
  T operator[](int i) const { return m_data[i]; }
  T &operator[](int i) { return m_data[i]; }

  size_t size() const { return m_size; }
  void reduce(size_t size) { m_size = size; }

  iterator begin() { return m_data; }
  iterator end() { return m_data + m_size; }
};

int pick_name(const string &s, map<string, int> &name_table) {
  map<string, int>::iterator it = name_table.find(s);
  if (it != name_table.end()) {
    return it->second;
  }
  int index = name_table.size();
  name_table.insert(make_pair(s, index));
  return index;
}

int main() {
  ios_base::sync_with_stdio(false);

  int N, T;
  cin >> N >> T;

  map<string, int> name_table;
  string A, B;
  cin >> A >> B;
  int start = pick_name(A, name_table);
  int goal = pick_name(B, name_table);

  fixed_vector<fixed_vector<int>> stations(N);
  fixed_vector<fixed_vector<int>> costs(N);
  int vertices_count = 0;
  for (int i = 0; i < N; ++i) {
    int a;
    cin >> a;
    vertices_count += a;
    stations[i] = fixed_vector<int>(a);
    costs[i] = fixed_vector<int>(a - 1);
    for (int j = 0; j < a; ++j) {
      string s;
      cin >> s;
      stations[i][j] = pick_name(s, name_table);
    }
    for (int j = 0; j + 1 < a; ++j) {
      cin >> costs[i][j];
    }
  }

  fixed_vector<int> platform_count(name_table.size());
  for (int i = 0; i < N; ++i) {
    int a = stations[i].size();
    for (int j = 0; j < a; ++j) {
      ++platform_count[stations[i][j]];
    }
  }
  fixed_vector<fixed_vector<int>> platforms(name_table.size());
  for (int i = 0; i < platforms.size(); ++i) {
    platforms[i] = fixed_vector<int>(platform_count[i]);
  }

  fixed_vector<fixed_vector<pii>> conn(vertices_count, fixed_vector<pii>(2));
  fixed_vector<int> conn_used_count(vertices_count, 0);
  fixed_vector<int> platform_used_count(platforms.size(), 0);
  fixed_vector<int> reverse_lookup(vertices_count);
  int vertex_index = 0;
  for (int i = 0; i < N; ++i) {
    int a = stations[i].size();
    int prev = vertex_index++, s = stations[i][0];
    platforms[s][platform_used_count[s]++] = prev;
    reverse_lookup[prev] = s;
    for (int j = 1; j < a; ++j) {
      int cur = vertex_index++;
      s = stations[i][j];
      platforms[s][platform_used_count[s]++] = cur;
      reverse_lookup[cur] = s;
      conn[prev][conn_used_count[prev]++] = pii(cur, costs[i][j - 1]);
      conn[cur][conn_used_count[cur]++] = pii(prev, costs[i][j - 1]);
      prev = cur;
    }
  }

  for (int i = 0; i < vertices_count; ++i) {
    conn[i].reduce(conn_used_count[i]);
  }
  for (int i = 0; i < platforms.size(); ++i) {
    sort(platforms[i].begin(), platforms[i].end());
  }

  fixed_vector<pii> mincost(conn.size(), pii(INF, INF));
  priority_queue<ppiii, vector<ppiii>, greater<ppiii>> pq;
  for (int i = 0; i < platforms[start].size(); ++i) {
    pq.push(ppiii(pii(0, 0), platforms[start][i]));
    mincost[platforms[start][i]] = pii(0, 0);
  }
  int time = -1, transit = 0;
  while (!pq.empty()) {
    ppiii pp = pq.top();
    pq.pop();
    int a = pp.first.first, t = pp.first.second, v = pp.second;
    if (mincost[v] < pp.first) {
      continue;
    }
    int s = reverse_lookup[v];
    if (s == goal) {
      time = a;
      transit = t;
      break;
    }
    for (int i = 0; i < platforms[s].size(); ++i) {
      pii cost(a + T, t + 1);
      if (mincost[platforms[s][i]] <= cost) {
        continue;
      }
      pq.push(ppiii(pii(a + T, t + 1), platforms[s][i]));
      mincost[platforms[s][i]] = cost;
    }
    for (int i = 0; i < conn[v].size(); ++i) {
      pii cost(a + conn[v][i].second, t);
      if (mincost[conn[v][i].first] <= cost) {
        continue;
      }
      pq.push(ppiii(pii(a + conn[v][i].second, t), conn[v][i].first));
      mincost[conn[v][i].first] = cost;
    }
  }
  if (time < 0) {
    cout << -1 << endl;
  } else {
    cout << time << " " << transit << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;

template <typename T> class fixed_vector {
  size_t m_size;
  T *m_data;

public:
  typedef T *iterator;

  explicit fixed_vector(size_t size = 0, const T &x = T()) : m_size(size) {
    m_data = new T[size];
    fill(m_data, m_data + size, x);
  }
  fixed_vector(const fixed_vector<T> &v) : m_size(v.m_size) {
    m_data = new T[m_size];
    copy(v.m_data, v.m_data + m_size, m_data);
  }
  ~fixed_vector() { delete[] m_data; }

  fixed_vector<T> &operator=(const fixed_vector<T> &v) {
    delete[] m_data;
    m_size = v.m_size;
    m_data = new T[m_size];
    copy(v.m_data, v.m_data + m_size, m_data);
  }
  T operator[](int i) const { return m_data[i]; }
  T &operator[](int i) { return m_data[i]; }

  size_t size() const { return m_size; }
  void reduce(size_t size) { m_size = size; }

  iterator begin() { return m_data; }
  iterator end() { return m_data + m_size; }
};

int pick_name(const string &s, map<string, int> &name_table) {
  map<string, int>::iterator it = name_table.find(s);
  if (it != name_table.end()) {
    return it->second;
  }
  int index = name_table.size();
  name_table.insert(make_pair(s, index));
  return index;
}

int main() {
  ios_base::sync_with_stdio(false);

  int N, T;
  cin >> N >> T;

  map<string, int> name_table;
  string A, B;
  cin >> A >> B;
  int start = pick_name(A, name_table);
  int goal = pick_name(B, name_table);

  fixed_vector<fixed_vector<int>> stations(N);
  fixed_vector<fixed_vector<int>> costs(N);
  int vertices_count = 0;
  for (int i = 0; i < N; ++i) {
    int a;
    cin >> a;
    vertices_count += a;
    stations[i] = fixed_vector<int>(a);
    costs[i] = fixed_vector<int>(a - 1);
    for (int j = 0; j < a; ++j) {
      string s;
      cin >> s;
      stations[i][j] = pick_name(s, name_table);
    }
    for (int j = 0; j + 1 < a; ++j) {
      cin >> costs[i][j];
    }
  }

  fixed_vector<int> platform_count(name_table.size());
  for (int i = 0; i < N; ++i) {
    int a = stations[i].size();
    for (int j = 0; j < a; ++j) {
      ++platform_count[stations[i][j]];
    }
  }
  fixed_vector<fixed_vector<int>> platforms(name_table.size());
  for (int i = 0; i < platforms.size(); ++i) {
    platforms[i] = fixed_vector<int>(platform_count[i]);
  }

  fixed_vector<fixed_vector<pii>> conn(vertices_count, fixed_vector<pii>(2));
  fixed_vector<int> conn_used_count(vertices_count, 0);
  fixed_vector<int> platform_used_count(platforms.size(), 0);
  fixed_vector<int> reverse_lookup(vertices_count);
  int vertex_index = 0;
  for (int i = 0; i < N; ++i) {
    int a = stations[i].size();
    int prev = vertex_index++, s = stations[i][0];
    platforms[s][platform_used_count[s]++] = prev;
    reverse_lookup[prev] = s;
    for (int j = 1; j < a; ++j) {
      int cur = vertex_index++;
      s = stations[i][j];
      platforms[s][platform_used_count[s]++] = cur;
      reverse_lookup[cur] = s;
      conn[prev][conn_used_count[prev]++] = pii(cur, costs[i][j - 1]);
      conn[cur][conn_used_count[cur]++] = pii(prev, costs[i][j - 1]);
      prev = cur;
    }
  }

  for (int i = 0; i < vertices_count; ++i) {
    conn[i].reduce(conn_used_count[i]);
  }
  for (int i = 0; i < platforms.size(); ++i) {
    sort(platforms[i].begin(), platforms[i].end());
  }

  fixed_vector<bool> passed(conn.size());
  priority_queue<ppiii, vector<ppiii>, greater<ppiii>> pq;
  for (int i = 0; i < platforms[start].size(); ++i) {
    pq.push(ppiii(pii(0, 0), platforms[start][i]));
  }
  int time = -1, transit = 0;
  while (!pq.empty()) {
    ppiii pp = pq.top();
    pq.pop();
    int a = pp.first.first, t = pp.first.second, v = pp.second;
    if (passed[v]) {
      continue;
    }
    passed[v] = true;
    int s = reverse_lookup[v];
    if (s == goal) {
      time = a;
      transit = t;
      break;
    }
    for (int i = 0; i < platforms[s].size(); ++i) {
      if (passed[platforms[s][i]]) {
        continue;
      }
      pq.push(ppiii(pii(a + T, t + 1), platforms[s][i]));
    }
    for (int i = 0; i < conn[v].size(); ++i) {
      if (passed[conn[v][i].first]) {
        continue;
      }
      pq.push(ppiii(pii(a + conn[v][i].second, t), conn[v][i].first));
    }
  }
  if (time < 0) {
    cout << -1 << endl;
  } else {
    cout << time << " " << transit << endl;
  }
  return 0;
}