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

#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

class State {
public:
  double d;
  int p, n;

  State(int pp, double dd = 0.0, int nn = 0) : p(pp), d(dd), n(nn) {}

  bool operator<(const State &s) const { return this->d > s.d; }
};

int main() {
  // freopen("1138.txt", "r", stdin);
  const double INF = 1000000000.0;

  int n, m, p, a, b;
  while (scanf("%d %d %d %d %d", &n, &m, &p, &a, &b) != EOF) {
    if (n == 0 && m == 0 && p == 0 && a == 0 && b == 0)
      break;
    --a;
    --b;

    vector<int> t(n);
    for (int i = 0; i < n; ++i)
      scanf("%d", &t[i]);

    vector<vector<int>> edge(m, vector<int>(m, -1));
    for (int i = 0; i < p; ++i) {
      int x, y, z;
      scanf("%d %d %d", &x, &y, &z);
      --x;
      --y;
      edge[x][y] = edge[y][x] = z;
    }

    double ans = INF;
    priority_queue<State> que;
    vector<vector<int>> visited(m, vector<int>(1 << (n + 1), 0));
    vector<vector<double>> cost(m, vector<double>(1 << (n + 1), INF));
    que.push(State(a));
    cost[0][0] = 0;

    while (!que.empty()) {
      State st = que.top();
      que.pop();

      if (st.p == b) {
        ans = st.d;
        break;
      }

      if (cost[st.p][st.n] < st.d || visited[st.p][st.n] ||
          st.n == (1 << (n + 1)))
        continue;

      visited[st.p][st.n] = 1;
      for (int i = 0; i < m; ++i) {
        if (edge[st.p][i] == -1)
          continue;

        for (int j = 1; j < n + 1; ++j) {
          if (st.n & (1 << j))
            continue;
          double tmp = st.d + edge[st.p][i] / static_cast<double>(t[j - 1]);
          if (cost[i][(1 << j) | st.n] > tmp) {
            cost[i][(1 << j) | st.n] = tmp;
            que.push(State(i, tmp, (1 << j) | st.n));
          }
        }
      }
    }

    if (ans == INF)
      printf("Impossible\\n");
    else
      printf("%.3f\\n", ans);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

class State {
public:
  double d;
  int p, n;

  State(int pp, double dd = 0.0, int nn = 0) : p(pp), d(dd), n(nn) {}

  bool operator<(const State &s) const { return this->d > s.d; }
};

int main() {
  // freopen("1138.txt", "r", stdin);
  const double INF = 1000000000.0;

  int n, m, p, a, b;
  while (scanf("%d %d %d %d %d", &n, &m, &p, &a, &b) != EOF) {
    if (n == 0 && m == 0 && p == 0 && a == 0 && b == 0)
      break;
    --a;
    --b;

    vector<int> t(n);
    for (int i = 0; i < n; ++i)
      scanf("%d", &t[i]);

    vector<vector<int>> edge(m, vector<int>(m, -1));
    for (int i = 0; i < p; ++i) {
      int x, y, z;
      scanf("%d %d %d", &x, &y, &z);
      --x;
      --y;
      edge[x][y] = edge[y][x] = z;
    }

    double ans = INF;
    priority_queue<State> que;
    vector<vector<double>> cost(m, vector<double>(1 << (n + 1), INF));
    que.push(State(a));
    cost[0][0] = 0;

    while (!que.empty()) {
      State st = que.top();
      que.pop();

      if (st.p == b) {
        ans = st.d;
        break;
      }

      if (st.n == (1 << (n + 1)))
        continue;

      for (int i = 0; i < m; ++i) {
        if (edge[st.p][i] == -1)
          continue;

        for (int j = 1; j < n + 1; ++j) {
          if (st.n & (1 << j))
            continue;
          double tmp = st.d + edge[st.p][i] / static_cast<double>(t[j - 1]);
          if (cost[i][(1 << j) | st.n] > tmp) {
            cost[i][(1 << j) | st.n] = tmp;
            que.push(State(i, tmp, (1 << j) | st.n));
          }
        }
      }
    }

    if (ans == INF)
      printf("Impossible\\n");
    else
      printf("%.3f\\n", ans);
  }

  return 0;
}