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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, len;
  Edge(int to0, int len0) {
    to = to0;
    len = len0;
  }
};

double INF = DBL_MAX / 2.0;
double EPS = 1.0e-7;

double solve(vector<int> &ticket, vector<vector<Edge>> &edges, int a, int b) {
  int n = ticket.size();
  int m = edges.size();

  vector<vector<double>> minCost(m, vector<double>(1 << n, INF));
  multimap<double, pair<int, int>> mm;
  mm.insert(make_pair(0.0, make_pair(a, (1 << n) - 1)));
  minCost[a][(1 << n) - 1] = 0.0;

  while (!mm.empty()) {
    multimap<double, pair<int, int>>::iterator it = mm.begin();
    double cost = it->first;
    int x = it->second.first;
    int y = it->second.second;
    mm.erase(it);

    if (x == b)
      return minCost[x][y];
    if (cost > minCost[x][y] + EPS)
      continue;

    bitset<8> bs(y);
    for (unsigned i = 0; i < edges[x].size(); ++i) {
      int to = edges[x][i].to;
      int len = edges[x][i].len;
      for (int j = 0; j < n; ++j) {
        if (!bs[j])
          continue;
        bs[j] = false;
        double cost1 = cost + (double)len / ticket[j];
        if (cost1 < minCost[to][bs.to_ulong()] - EPS) {
          minCost[to][bs.to_ulong()] = cost1;
          mm.insert(make_pair(cost1, make_pair(to, bs.to_ulong())));
        }
        bs[j] = true;
      }
    }
  }

  return INF;
}

int main() {
  for (;;) {
    int n, m, p, a, b;
    cin >> n >> m >> p >> a >> b;
    if (n == 0)
      break;

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

    vector<vector<Edge>> edges(m);
    for (int i = 0; i < p; ++i) {
      int x, y, z;
      cin >> x >> y >> z;
      edges[x - 1].push_back(Edge(y - 1, z));
      edges[y - 1].push_back(Edge(x - 1, z));
    }

    double ret = solve(ticket, edges, a - 1, b - 1);
    if (ret == INF)
      cout << "Impossible" << endl;
    else
      printf("%.10f\\n", ret);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, len;
  Edge(int to0, int len0) {
    to = to0;
    len = len0;
  }
};

double INF = DBL_MAX / 2.0;

double solve(vector<int> &ticket, vector<vector<Edge>> &edges, int a, int b) {
  int n = ticket.size();
  int m = edges.size();

  vector<vector<double>> dp(m, vector<double>(1 << n, INF));
  multimap<double, pair<int, int>> mm;
  mm.insert(make_pair(0.0, make_pair(a, (1 << n) - 1)));
  dp[a][(1 << n) - 1] = 0.0;

  while (!mm.empty()) {
    multimap<double, pair<int, int>>::iterator it = mm.begin();
    double cost = it->first;
    int x = it->second.first;
    int y = it->second.second;
    mm.erase(it);

    if (x == b)
      return dp[x][y];
    if (dp[x][y] < cost)
      continue;

    bitset<8> bs(y);
    for (unsigned i = 0; i < edges[x].size(); ++i) {
      int to = edges[x][i].to;
      int len = edges[x][i].len;
      for (int j = 0; j < n; ++j) {
        if (!bs[j])
          continue;
        bs[j] = false;
        if (cost + (double)len / ticket[j] < dp[to][bs.to_ulong()]) {
          dp[to][bs.to_ulong()] = cost + (double)len / ticket[j];
          mm.insert(make_pair(cost + (double)len / ticket[j],
                              make_pair(to, bs.to_ulong())));
        }
        bs[j] = true;
      }
    }
  }

  return INF;
}

int main() {
  for (;;) {
    int n, m, p, a, b;
    cin >> n >> m >> p >> a >> b;
    if (n == 0)
      break;

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

    vector<vector<Edge>> edges(m);
    for (int i = 0; i < p; ++i) {
      int x, y, z;
      cin >> x >> y >> z;
      edges[x - 1].push_back(Edge(y - 1, z));
      edges[y - 1].push_back(Edge(x - 1, z));
    }

    double ret = solve(ticket, edges, a - 1, b - 1);
    if (ret == INF)
      cout << "Impossible" << endl;
    else
      printf("%.10f\\n", ret);
  }
}