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

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int inf = 1e9;

struct station {
  int st;
  int c, h, r;
  station(int st, int c, int h, int r) : st(st), c(c), h(h), r(r) {}
  station() {}
};
struct info {
  int pos, cost, time;
  info(int p, int c, int t) : pos(p), cost(c), time(t) {}
  info();
  bool operator<(const info &a) const {
    return (cost != a.cost) ? cost > a.cost : time < a.time;
  }
};

int solve(int s, int g, int time, int pass, vector<vector<station>> &adj) {
  vector<vector<int>> mincost(adj.size(), vector<int>(time + 1, inf));
  for (int i = 0; i <= time; i++) {
    mincost[s][i] = 0;
  }
  priority_queue<info> wait;
  wait.push(info(s, 0, time));
  while (!wait.empty()) {
    int p = wait.top().pos;
    int c = wait.top().cost;
    int t = wait.top().time;
    wait.pop();
    if (c > mincost[p][t])
      continue;
    if (p == g)
      return c;

    for (int i = 0; i < (int)adj[p].size(); i++) {
      station next = adj[p][i];
      int npos = next.st;
      int ncost = ((pass & 1 << next.r) != 0) ? c : c + next.c;
      int ntime = t - next.h;
      if (ntime < 0 || ncost >= mincost[npos][ntime])
        continue;
      for (int j = 0; j <= ntime; j++) {
        mincost[npos][j] = min(mincost[npos][j], ncost);
      }
      wait.push(info(npos, ncost, ntime));
    }
  }
  return inf;
}

int main() {
  while (1) {
    int n, m, h, k;
    cin >> n >> m >> h >> k;
    if (n == 0)
      break;

    vector<vector<station>> adj(n);
    for (int i = 0; i < m; i++) {
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r;
      a--;
      b--;
      r--;
      adj[a].push_back(station(b, c, h, r));
      adj[b].push_back(station(a, c, h, r));
    }

    int s, t, p;
    cin >> s >> t >> p;
    s--;
    t--;
    vector<int> dp(1 << k, inf);
    dp[0] = 0;
    for (int i = 0; i < p; i++) {
      int num, d, pass = 0;
      cin >> num >> d;
      for (int j = 0; j < num; j++) {
        int k;
        cin >> k;
        k--;
        pass |= 1 << k;
      }
      for (int j = 0; j < (1 << k); j++) {
        if (dp[j] != inf) {
          dp[j | pass] = min(dp[j | pass], dp[j] + d);
        }
      }
    }

    int ans = inf;
    for (int i = 0; i < (1 << k); i++) {
      if (dp[i] >= ans)
        continue;
      ans = min(ans, dp[i] + solve(s, t, h, i, adj));
    }

    if (ans == inf) {
      cout << -1 << endl;
    } else {
      cout << ans << endl;
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int inf = 1e9;

struct station {
  int st;
  int c, h, r;
  station(int st, int c, int h, int r) : st(st), c(c), h(h), r(r) {}
  station() {}
};

int used[100] = {};
int solve(int pos, int t, int time, int pass, vector<vector<station>> &adj) {
  if (time < 0)
    return inf;
  if (pos == t)
    return 0;
  int ret = inf;
  for (int i = 0; i < (int)adj[pos].size(); i++) {
    station next = adj[pos][i];
    if (used[next.st] == 1)
      continue;
    used[next.st] = 1;
    int cost = ((pass & 1 << next.r) != 0) ? 0 : next.c;
    ret = min(ret, cost + solve(next.st, t, time - next.h, pass, adj));
    used[next.st] = 0;
  }
  return ret;
}

int main() {
  while (1) {
    int n, m, h, k;
    cin >> n >> m >> h >> k;
    if (n == 0)
      break;

    vector<vector<station>> adj(n);
    for (int i = 0; i < m; i++) {
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r;
      a--;
      b--;
      r--;
      adj[a].push_back(station(b, c, h, r));
      adj[b].push_back(station(a, c, h, r));
    }

    int s, t, p;
    cin >> s >> t >> p;
    s--;
    t--;
    vector<int> dp(1 << k, inf);
    dp[0] = 0;
    for (int i = 0; i < p; i++) {
      int num, d, pass = 0;
      cin >> num >> d;
      for (int j = 0; j < num; j++) {
        int k;
        cin >> k;
        k--;
        pass |= 1 << k;
      }
      for (int j = 0; j < (1 << k); j++) {
        if (dp[j] != inf) {
          dp[j | pass] = min(dp[j | pass], dp[j] + d);
        }
      }
    }

    int ans = inf;
    for (int i = 0; i < (1 << k); i++) {
      if (dp[i] == inf)
        continue;
      ans = min(ans, dp[i] + solve(s, t, h, i, adj));
    }

    if (ans == inf) {
      cout << -1 << endl;
    } else {
      cout << ans << endl;
    }
  }
  return 0;
}