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

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;

struct edge {
  int from, to, cost;
};
// typedef pair<int, int > P;
// typedef pair<double, P> S;

const double INF = 9999999.0;
const double EPS = 1e-5;

int n, m, p, a, b, st, gl;

int t[8];
double dp[31][1 << 8];

int main() {
  while (cin >> n >> m >> p >> a >> b && (n || m || p || a || b)) {

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

    vector<vector<edge>> es(m + 1);

    int x, y, z;
    for (int i = 0; i < p; i++) {
      cin >> x >> y >> z;
      es[x].push_back((edge){x, y, z});
      es[y].push_back((edge){y, x, z});
    }

    for (int i = 1; i <= m; i++)
      for (int k = 0; k < (1 << n); k++)
        dp[i][k] = INF;

    double ans = INF;
    dp[a][(1 << n) - 1] = 0.0;
    for (int S = (1 << n) - 1; S >= 0; S--) {
      ans = min(ans, dp[b][S]);
      for (int v = 1; v <= m; v++) {
        for (int i = 0; i < n; i++) {
          if ((1 << i) & S) {
            for (int u = 0; u < es[v].size(); u++) {
              int to = es[v][u].to;
              // cout << v << " => " << to << endl;
              dp[to][S & ~(1 << i)] =
                  min(dp[to][S & ~(1 << i)],
                      dp[v][S] + (double)es[v][u].cost / t[i]);
            }
          }
        }
      }
    }

    if (ans + EPS > INF)
      cout << "Impossible" << endl;
    else
      printf("%.3lf\\n", ans);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;

struct edge {
  int from, to, cost;
};
typedef pair<int, int> P;
typedef pair<double, P> S;

const double INF = 9999999.0;
const double EPS = 1e-5;

int n, m, p, a, b;

int t[8];
double dp[31][1 << 8];

int main() {
  while (cin >> n >> m >> p >> a >> b && (n || m || p || a || b)) {

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

    if (a != b && p == 0) {
      cout << "Impossible" << endl;
      continue;
    }

    vector<vector<edge>> es(m + 1);

    int x, y, z;
    for (int i = 0; i < p; i++) {
      cin >> x >> y >> z;
      es[x].push_back((edge){x, y, z});
      es[y].push_back((edge){y, x, z});
    }

    for (int i = 1; i <= m; i++)
      for (int k = 0; k <= (1 << n); k++)
        dp[i][k] = INF;

    priority_queue<S, vector<S>, greater<S>> que;
    que.push(S(0.0, P(a, 0)));
    double ans;
    bool goal = false;
    while (!que.empty()) {
      S s = que.top();
      que.pop();
      double cost = s.first;
      int from = s.second.first, ticket = s.second.second;

      if (dp[from][ticket] + EPS < cost)
        continue;

      dp[from][ticket] = cost;

      if (from == b) {
        ans = cost;
        goal = true;
        break;
      }

      for (int i = 0; i < es[from].size(); i++) {
        int to = es[from][i].to;
        for (int j = 0; j < n; j++) {
          int use = 1 << j;
          cost = (double)es[from][i].cost / t[j] + dp[from][ticket];
          if ((ticket & use) == 0 && cost + EPS < dp[to][ticket])
            que.push(S(cost, P(to, ticket | use)));
        }
      }
    }

    if (!goal)
      cout << "Impossible" << endl;
    else
      printf("%.3lf\\n", ans);
  }
}