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

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#define INF (1e9)
#define N 8
#define M 31
using namespace std;
typedef pair<int, int> P0;
typedef pair<double, P0> P;
typedef pair<int, int> P1;
double dijkstra();
int n, m, p, a, b, ti[N];
double d[(1 << N)][M], ans;
vector<P1> edge[M];

int main() {
  int x, y, z;
  while (1) {
    cin >> n >> m >> p >> a >> b;
    if (!n && !m && !p && !a && !b)
      break;
    for (int i = 0; i < n; i++)
      cin >> ti[i];
    a--, b--;
    while (p--) {
      cin >> x >> y >> z;
      x--, y--;
      edge[x].push_back(P1(y, z));
      edge[y].push_back(P1(x, z));
    }
    ans = INF;
    ans = dijkstra();
    if (ans == INF)
      cout << "Impossible" << endl;
    else
      cout << ans << endl;
    for (int i = 0; i < m; i++)
      edge[i].clear();
  }
  return 0;
}

double dijkstra() {
  priority_queue<P, vector<P>, greater<P>> q;
  for (int i = 0; i < (1 << n); i++)
    for (int j = 0; j < m; j++)
      d[i][j] = INF;
  d[0][a] = 0;
  q.push(P(0, P0(0, a)));
  while (!q.empty()) {
    P t = q.top();
    q.pop();
    double cost = t.first;
    int uy = t.second.first, ux = t.second.second;
    if (d[uy][ux] < cost)
      continue;
    for (int i = 0; i < edge[ux].size(); i++) {
      int nx = edge[ux][i].first;
      for (int j = 0; j < n; j++) {
        double c = cost + 1.0 * edge[ux][i].second / ti[j];
        if ((uy & (1 << j)) == 0) {
          int ny = uy | (1 << j);
          if (d[ny][nx] > c) {
            d[ny][nx] = c;
            q.push(P(c, P0(ny, nx)));
          }
        }
      }
    }
  }
  double res = INF;
  for (int i = 0; i < (1 << n); i++)
    res = min(res, d[i][b]);
  return res;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#define INF (1e9)
#define N 9
#define M 31
using namespace std;
typedef pair<int, int> P0;
typedef pair<double, P0> P;
typedef pair<int, int> P1;
void NP(int);
double dijkstra();
int np[N], used[N + 1], n, m, p, a, b, ti[N];
double d[N + 1][M], ans;
vector<P1> edge[M];

int main() {
  int x, y, z;
  while (1) {
    cin >> n >> m >> p >> a >> b;
    if (!n && !m && !p && !a && !b)
      break;
    for (int i = 0; i < n; i++)
      cin >> ti[i];
    a--, b--;
    while (p--) {
      cin >> x >> y >> z;
      x--, y--;
      edge[x].push_back(P1(y, z));
      edge[y].push_back(P1(x, z));
    }
    ans = INF;
    NP(0);
    if (ans == INF)
      cout << "Impossible" << endl;
    else
      cout << ans << endl;
    for (int i = 0; i < m; i++)
      edge[i].clear();
  }
  return 0;
}

void NP(int x) {
  if (x == n) {
    ans = min(ans, dijkstra());
  } else {
    for (int i = 0; i < n; i++) {
      if (used[i])
        continue;
      used[i] = true;
      np[x] = i;
      NP(x + 1);
      used[i] = false;
    }
  }
}

double dijkstra() {
  priority_queue<P> q;
  for (int i = 0; i <= n; i++)
    for (int j = 0; j < m; j++)
      d[i][j] = INF;
  d[0][a] = 0;
  q.push(P(0, P0(0, a)));
  while (!q.empty()) {
    P t = q.top();
    q.pop();
    double cost = -t.first;
    int uy = t.second.first, ux = t.second.second, ny = uy + 1;
    if (d[uy][ux] < cost || uy == n)
      continue;
    for (int i = 0; i < edge[ux].size(); i++) {
      int nx = edge[ux][i].first;
      double c = cost + 1.0 * edge[ux][i].second / ti[np[uy]];
      if (d[ny][nx] > c) {
        d[ny][nx] = c;
        q.push(P(-c, P0(ny, nx)));
      }
    }
  }
  double res = INF;
  for (int i = 0; i <= n; i++)
    res = min(res, d[i][b]);
  return res;
}