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

#include <bits/stdc++.h>
using namespace std;
typedef struct edge {
  int cost, to, time, com;
} edge;
typedef struct pass {
  int com = 0, cost = 0;
} pass;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
int n, m, h, k, s, t, p;
int dp[(1 << 9)][30][111];
vector<vector<edge>> g;
vector<pass> vp;

void init() {
  g.resize(n);
  for (int i = 0; i < (1 << k); i++) {
    for (int j = 0; j <= h; j++) {
      for (int k = 0; k <= n; k++) {
        dp[i][j][k] = 1e9;
      }
    }
  }
  for (int i = 0; i < m; i++) {
    int from, to;
    edge e;
    std::cin >> from >> to >> e.cost >> e.time >> e.com;
    from--, to--, e.com--;
    e.to = to;
    g[from].emplace_back(e);
    e.to = from;
    g[to].emplace_back(e);
  }
  std::cin >> s >> t >> p;
  s--, t--;
  vp.resize(p);
  for (int i = 0; i < p; i++) {
    int l, c;
    std::cin >> l >> vp[i].cost;
    for (int j = 0; j < l; j++) {
      std::cin >> c;
      c--;
      vp[i].com |= (1 << c);
    }
  }
}

void dijkstra(int com, int cost) {
  priority_queue<piii, vector<piii>, greater<piii>> que;
  dp[com][0][s] = cost;
  que.push(piii(cost, pii(s, 0)));
  while (not que.empty()) {
    int c = que.top().first;
    int v = que.top().second.first;
    int t = que.top().second.second;
    que.pop();
    for (int i = 0; i < g[v].size(); i++) {
      edge &e = g[v][i];
      int nt = t + e.time;
      int nc = c;
      if ((com & (1 << e.com)) == 0)
        nc += e.cost;
      if (nt <= h and dp[com][nt][e.to] > nc) {
        dp[com][nt][e.to] = nc;
        que.push(piii(nc, pii(e.to, nt)));
      }
    }
  }
}

int main() {
  while (std::cin >> n >> m >> h >> k, n) {
    g.clear();
    vp.clear();
    init();
    int ans = 1e9;
    int pass_cost[(1 << k)];
    for (int i = 0; i < (1 << k); i++) {
      pass_cost[i] = 1e9;
    }
    queue<pii> que;
    que.push(pii(0, 0));
    pass_cost[0] = 0;
    while (not que.empty()) {
      int v = que.front().first;
      int c = que.front().second;
      que.pop();
      for (int i = 0; i < p; i++) {
        int nv = v | vp[i].com;
        if (pass_cost[nv] > c + vp[i].cost) {
          pass_cost[nv] = c + vp[i].cost;
          que.push(pii(nv, pass_cost[nv]));
        }
      }
    }
    for (int i = 0; i < (1 << k); i++) {
      if (pass_cost[i] != 1e9)
        dijkstra(i, pass_cost[i]);
    }
    for (int i = 0; i < (1 << k); i++) {
      for (int j = 0; j <= h; j++) {
        ans = min(ans, dp[i][j][t]);
      }
    }
    if (ans != 1e9)
      std::cout << ans << std::endl;
    else
      std::cout << -1 << std::endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef struct edge {
  int cost, to, time, com;
} edge;
typedef struct pass {
  int com = 0, cost = 0;
} pass;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
int n, m, h, k, s, t, p;
int dp[(1 << 9)][30][111];
vector<vector<edge>> g;
vector<pass> vp;

void init() {
  g.resize(n);
  for (int i = 0; i < (1 << k); i++) {
    for (int j = 0; j <= h; j++) {
      for (int k = 0; k <= n; k++) {
        dp[i][j][k] = 1e9;
      }
    }
  }
  for (int i = 0; i < m; i++) {
    int from, to;
    edge e;
    std::cin >> from >> to >> e.cost >> e.time >> e.com;
    from--, to--, e.com--;
    e.to = to;
    g[from].emplace_back(e);
    e.to = from;
    g[to].emplace_back(e);
  }
  std::cin >> s >> t >> p;
  s--, t--;
  vp.resize(p);
  for (int i = 0; i < p; i++) {
    int l, c;
    std::cin >> l >> vp[i].cost;
    for (int j = 0; j < l; j++) {
      std::cin >> c;
      c--;
      vp[i].com |= (1 << c);
    }
  }
}

void dijkstra(int com, int cost) {
  priority_queue<piii, vector<piii>, greater<piii>> que;
  dp[com][0][s] = cost;
  que.push(piii(cost, pii(s, 0)));
  while (not que.empty()) {
    int c = que.top().first;
    int v = que.top().second.first;
    int t = que.top().second.second;
    que.pop();
    for (int i = 0; i < g[v].size(); i++) {
      edge &e = g[v][i];
      int nt = t + e.time;
      int nc = c;
      if ((com & (1 << e.com)) == 0)
        nc += e.cost;
      if (nt <= h and dp[com][nt][e.to] > nc) {
        dp[com][nt][e.to] = nc;
        que.push(piii(nc, pii(e.to, nt)));
      }
    }
  }
}

int main() {
  while (std::cin >> n >> m >> h >> k, n) {
    g.clear();
    vp.clear();
    init();
    int ans = 1e9;
    int pass_cost[(1 << k)];
    for (int i = 0; i < (1 << k); i++) {
      pass_cost[i] = 1e9;
    }
    for (int i = 0; i < (1 << p); i++) {
      int cost = 0, com = 0;
      for (int j = 0; j < p; j++) {
        if ((i & (1 << j)) > 0) {
          cost += vp[j].cost;
          com |= vp[j].com;
        }
      }
      pass_cost[com] = min(pass_cost[com], cost);
    }
    for (int i = 0; i < (1 << k); i++) {
      if (pass_cost[i] != 1e9)
        dijkstra(i, pass_cost[i]);
    }
    for (int i = 0; i < (1 << k); i++) {
      for (int j = 0; j <= h; j++) {
        ans = min(ans, dp[i][j][t]);
      }
    }
    if (ans != 1e9)
      std::cout << ans << std::endl;
    else
      std::cout << -1 << std::endl;
  }
  return 0;
}