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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

struct Line {
  int a, b, cost, time, company;
} lines[500];

struct Passpotr {
  int cost, company;
} pass[1 << 8];

ll pass_cost[1 << 8];

typedef long long W;

const W INF = 1LL << 50;

struct edge {
  int to;
  W cost;
};
typedef pair<W, int> P;
typedef vector<vector<edge>> Graph;

void dijkstra(int s, const Graph G, vector<W> &d) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d.begin(), d.end(), INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

int toV(int n, int h) { return 25 * n + h; }

Graph G(25 * 100);
vector<W> d(25 * 100);

int main() {
  int n, m, k, h, s, g, p;
  while (scanf("%d %d %d %d", &n, &m, &h, &k), n) {
    for (int i = 0; i < m; i++) {
      scanf("%d %d %d %d %d", &lines[i].a, &lines[i].b, &lines[i].cost,
            &lines[i].time, &lines[i].company);
      lines[i].a--, lines[i].b--, lines[i].company--;
    }
    scanf("%d %d %d", &s, &g, &p);
    s--, g--;

    for (int i = 0; i < p; i++) {
      int l;
      scanf("%d %d", &l, &pass[i].cost);
      pass[i].company = 0;
      for (int j = 0; j < l; j++) {
        int cp;
        scanf("%d", &cp);
        cp--;
        pass[i].company |= 1 << cp;
      }
    }

    for (int i = 0; i < 1 << k; i++) {
      pass_cost[i] = INF;
    }
    pass_cost[0] = 0;
    for (int i = 0; i < p; i++) {
      for (int j = 0; j < 1 << k; j++) {
        pass_cost[j | pass[i].company] =
            min(pass_cost[j | pass[i].company], pass_cost[j] + pass[i].cost);
      }
    }

    ll ans = INF;
    for (int free = 0; free < 1 << k; free++) {
      if (pass_cost[free] == INF)
        continue;

      for (int i = 0; i < n; i++) {
        for (int j = 0; j < 25; j++) {
          G[toV(i, j)].clear();
        }
      }

      for (int i = 0; i < m; i++) {
        Line l = lines[i];
        int c = l.cost;
        if (free & (1 << l.company))
          c = 0;

        for (int j = 0; j < h; j++) {
          if (j + l.time > h)
            continue;
          G[toV(l.a, j)].push_back(edge{toV(l.b, j + l.time), c});
          G[toV(l.b, j)].push_back(edge{toV(l.a, j + l.time), c});
        }
      }

      dijkstra(toV(s, 0), G, d);
      for (int i = 0; i <= h; i++) {
        ans = min(ans, pass_cost[free] + d[toV(g, i)]);
      }
    }

    printf("%lld\\n", ((ans == INF) ? -1 : ans));
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

struct Line {
  int a, b, cost, time, company;
} lines[500];

struct Passpotr {
  int cost, company;
} pass[1 << 8];

ll pass_cost[1 << 8];

typedef long long W;

const W INF = 1LL << 50;

struct edge {
  int to;
  W cost;
};
typedef pair<W, int> P;
typedef vector<vector<edge>> Graph;

void dijkstra(int s, const Graph G, vector<W> &d) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d.begin(), d.end(), INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

int toV(int n, int h) { return 25 * n + h; }

int main() {
  int n, m, k, h, s, g, p;
  while (scanf("%d %d %d %d", &n, &m, &h, &k), n) {
    for (int i = 0; i < m; i++) {
      scanf("%d %d %d %d %d", &lines[i].a, &lines[i].b, &lines[i].cost,
            &lines[i].time, &lines[i].company);
      lines[i].a--, lines[i].b--, lines[i].company--;
    }
    scanf("%d %d %d", &s, &g, &p);
    s--, g--;

    for (int i = 0; i < p; i++) {
      int l;
      scanf("%d %d", &l, &pass[i].cost);
      pass[i].company = 0;
      for (int j = 0; j < l; j++) {
        int cp;
        scanf("%d", &cp);
        cp--;
        pass[i].company |= 1 << cp;
      }
    }

    for (int i = 0; i < 1 << k; i++) {
      pass_cost[i] = INF;
    }
    pass_cost[0] = 0;
    for (int i = 0; i < p; i++) {
      for (int j = 0; j < 1 << k; j++) {
        pass_cost[j | pass[i].company] =
            min(pass_cost[j | pass[i].company], pass_cost[j] + pass[i].cost);
      }
    }

    ll ans = INF;
    for (int free = 0; free < 1 << k; free++) {
      if (pass_cost[free] == INF)
        continue;

      Graph G(25 * n);
      for (int i = 0; i < m; i++) {
        Line l = lines[i];
        int c = l.cost;
        if (free & (1 << l.company))
          c = 0;

        for (int j = 0; j < h; j++) {
          if (j + l.time > h)
            continue;
          G[toV(l.a, j)].push_back(edge{toV(l.b, j + l.time), c});
          G[toV(l.b, j)].push_back(edge{toV(l.a, j + l.time), c});
        }
      }

      vector<W> d(25 * n);
      dijkstra(toV(s, 0), G, d);
      for (int i = 0; i <= h; i++) {
        ans = min(ans, pass_cost[free] + d[toV(g, i)]);
      }
    }

    printf("%lld\\n", ((ans == INF) ? -1 : ans));
  }
}