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

#include <algorithm>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int, int> CostSet;
typedef pair<float, CostSet *> StateSet;

const float INITIAL_COST = 3000.0;

int coupon_index(bool *coupons, int size) {
  int index = 0;
  for (int i = 0; i < size; index += (1 << i) * (coupons[i] > 0 ? 1 : 0), i++)
    ;
  return index;
}

class StateOrder {
public:
  bool operator()(StateSet *a, StateSet *b) { return a->first > b->first; }
};

// dp
float mod_dijkstra(int **adj_mat, int *coupons, int start, int goal, int size,
                   int cpn_size) {

  priority_queue<StateSet *, vector<StateSet *>, StateOrder> nodes;

  //    auto avail_tickets = new bool[cpn_size];

  //    for (int i = 0; i < cpn_size; avail_tickets[i++] = true);

  int cpn_max = (1 << cpn_size) - 1;

  int avail_tickets = cpn_max;

  float cpn_costs[size][cpn_max];

  for (int i = 0; i < size; i++)
    for (int j = 0; j < cpn_max; j++)
      cpn_costs[i][j] = INITIAL_COST;

  cpn_costs[start][cpn_max - 1] = 0.0;

  auto e = new CostSet(start, avail_tickets);

  nodes.push(new StateSet(0.0, e));

  while (!nodes.empty()) {

    auto node = nodes.top();
    nodes.pop();

    e = node->second;
    int from_index = e->first;

    float now_cost = node->first;

    if (from_index == goal) {

      return now_cost;
    }

    avail_tickets = e->second;

    for (int to_index = 0; to_index < size; to_index++) {
      for (int i = 0; i < cpn_size; i++) {
        int check_bit = 1 << i;
        if (avail_tickets & check_bit) {
          int next_tickets = avail_tickets - check_bit;

          float from_to_cost = (float)adj_mat[from_index][to_index];

          if (from_to_cost == 0.0) {
            break;
          }

          float total_cost = now_cost + from_to_cost / (float)coupons[i];

          if (cpn_costs[to_index][next_tickets] > total_cost) {
            cpn_costs[to_index][next_tickets] = total_cost;
            nodes.push(
                new StateSet(total_cost, new CostSet(to_index, next_tickets)));
          }
        }
      }
    }

    delete e;
    delete node;
  }

  return INITIAL_COST;
}

int main() {

  int n, m, p, a, b;

  while (cin >> n >> m >> p >> a >> b, n != 0) {

    int t[n];

    for (int i = 0; i < n; cin >> t[i++])
      ;

    int **adj_mat = new int *[m];

    for (int i = 0; i < m; adj_mat[i++] = new int[m]())
      ;

    for (int i = 0; i < p; i++) {
      int x, y, z;
      cin >> x >> y >> z;

      adj_mat[x - 1][y - 1] = z;
      adj_mat[y - 1][x - 1] = z;
    }

    float cost = mod_dijkstra(adj_mat, t, a - 1, b - 1, m, n);

    cout << (p == 0 || cost >= INITIAL_COST ? "Impossible" : to_string(cost))
         << endl;

    for (int i = 0; i < m; delete[] adj_mat[i++])
      ;

    delete[] adj_mat;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int, bool *> CostSet;
typedef pair<float, CostSet *> StateSet;

const float INITIAL_COST = 3000.0;

int coupon_index(bool *coupons, int size) {
  int index = 0;
  for (int i = 0; i < size; index += (1 << i) * (coupons[i] > 0 ? 1 : 0), i++)
    ;
  return index;
}

class StateOrder {
public:
  bool operator()(StateSet *a, StateSet *b) { return a->first > b->first; }
};

// dp
float mod_dijkstra(int **adj_mat, int *coupons, int start, int goal, int size,
                   int cpn_size) {

  priority_queue<StateSet *, vector<StateSet *>, StateOrder> nodes;

  auto avail_tickets = new bool[cpn_size];

  for (int i = 0; i < cpn_size; avail_tickets[i++] = true)
    ;

  int cpn_max = (1 << cpn_size) - 1;

  float cpn_costs[size][cpn_max];

  for (int i = 0; i < size; i++)
    for (int j = 0; j < cpn_max; j++)
      cpn_costs[i][j] = INITIAL_COST;

  cpn_costs[start][cpn_max - 1] = 0.0;

  auto e = new CostSet(start, avail_tickets);

  nodes.push(new StateSet(0.0, e));

  while (!nodes.empty()) {

    auto node = nodes.top();
    nodes.pop();

    e = node->second;
    int from_index = e->first;

    if (from_index == goal) {
      return node->first;
    }

    avail_tickets = e->second;

    for (int to_index = 0; to_index < size; to_index++) {
      for (int i = 0; i < cpn_size; i++) {
        if (avail_tickets[i]) {
          auto next_tickets = new bool[cpn_size];
          copy(avail_tickets, avail_tickets + cpn_size, next_tickets);
          next_tickets[i] = false;

          float from_to_cost = (float)adj_mat[from_index][to_index];

          if (from_to_cost == 0.0) {
            break;
          }

          int cpn_index = coupon_index(next_tickets, cpn_size);

          float total_cost = node->first + from_to_cost / (float)coupons[i];

          if (cpn_costs[to_index][cpn_index] > total_cost) {
            cpn_costs[to_index][cpn_index] = total_cost;
            nodes.push(
                new StateSet(total_cost, new CostSet(to_index, next_tickets)));
          }
        }
      }
    }

    delete[] avail_tickets;
    delete e;
    delete node;
  }

  return INITIAL_COST;
}

int main() {

  int n, m, p, a, b;

  while (cin >> n >> m >> p >> a >> b, n != 0) {

    int t[n];

    for (int i = 0; i < n; cin >> t[i++])
      ;

    int **adj_mat = new int *[m];

    for (int i = 0; i < m; adj_mat[i++] = new int[m]())
      ;

    for (int i = 0; i < p; i++) {
      int x, y, z;
      cin >> x >> y >> z;

      adj_mat[x - 1][y - 1] = z;
      adj_mat[y - 1][x - 1] = z;
    }

    float cost = mod_dijkstra(adj_mat, t, a - 1, b - 1, m, n);

    cout << (p == 0 || cost >= INITIAL_COST ? "Impossible" : to_string(cost))
         << endl;

    for (int i = 0; i < m; delete[] adj_mat[i++])
      ;

    delete[] adj_mat;
  }

  return 0;
}