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

#include <bits/stdc++.h>

using namespace std;

// #define LOG(...) fprintf(stderr, __VA_ARGS__)
#define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SQ(n) (n) * (n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = (int)1e9;

struct Edge {
  int to, cost, time, campany;
};

struct Passport {
  int cost, campany;
};

struct P {
  int p, cost, time;

  bool operator>(const P &p) const { return cost > p.cost; }
};

int G[101][25];

int main() {
  int node_n, edge_n, max_time, campany_n;
  while (cin >> node_n >> edge_n >> max_time >> campany_n,
         node_n | edge_n | max_time | campany_n) {
    vector<vector<Edge>> E(node_n + 1);
    LOG("dddddddd\\n");
    REP(i, edge_n) {
      int from, to, cost, time, campany;
      cin >> from >> to >> cost >> time >> campany;
      campany--;
      E[from].push_back({to, cost, time, 1 << campany});
      E[to].push_back({from, cost, time, 1 << campany});
    }
    int start, goal, passport_n;
    cin >> start >> goal >> passport_n;
    vector<Passport> pass(passport_n);
    LOG("cccccccccc\\n");
    REP(i, passport_n) {
      int camp_n;
      cin >> camp_n;
      cin >> pass[i].cost;
      REP(j, camp_n) {
        int camp;
        cin >> camp;
        camp--;
        pass[i].campany |= (1 << camp);
      }
    }

    vi campany_cost(1 << campany_n, INF);
    campany_cost[0] = 0;
    REP(i, 1 << campany_n) {
      if (campany_cost[i] == INF)
        continue;
      REP(j, passport_n) {
        campany_cost[i | pass[j].campany] = min(
            campany_cost[i | pass[j].campany], campany_cost[i] + pass[j].cost);
      }
    }

    LOG("costttttt\\n");
    for (int c : campany_cost) {
      LOG("%d\\n", c);
    }
    LOG("costttttt\\n");

    int res = INF;
    LOG("bbbbbbbbb\\n");
    REP(i, 1 << campany_n) {
      LOG("aaaaaaaaaaaaaa\\n");
      if (campany_cost[i] == INF)
        continue;
      fill_n((int *)G, 25 * 101, INF);
      G[start][0] = campany_cost[i];
      int free_campany = i;

      priority_queue<P, vector<P>, greater<P>> que;
      que.push({start, G[start][0], 0});
      while (!que.empty()) {
        P p = que.top();
        que.pop();
        LOG(">>> p:%d  cpst:%d\\n", p.p, p.cost);
        if (p.p == goal) {
          res = min(res, p.cost);
          break;
        }

        for (Edge e : E[p.p]) {
          LOG(" -- %d\\n", e.to);
          int next_cost = p.cost + e.cost;
          if (e.campany & free_campany)
            next_cost -= e.cost;
          int next_time = p.time + e.time;
          if (next_time > max_time)
            continue;
          if (G[e.to][next_time] > next_cost) {
            G[e.to][next_time] = next_cost;
            LOG("p %d  cost:%d\\n", e.to, next_cost);
            que.push({e.to, next_cost, next_time});
          }
        }
      }
    }

    if (res == INF) {
      cout << -1 << endl;
    } else {
      cout << res << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

// #define LOG(...) fprintf(stderr, __VA_ARGS__)
#define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SQ(n) (n) * (n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = (int)1e9;

struct Edge {
  int to, cost, time, campany;
};

struct Passport {
  int cost, campany;
};

struct P {
  int p, cost, time;

  bool operator>(const P &p) const { return cost > p.cost; }
};

int G[101][25];

int main() {
  int node_n, edge_n, max_time, campany_n;
  while (cin >> node_n >> edge_n >> max_time >> campany_n,
         node_n | edge_n | max_time | campany_n) {
    vector<vector<Edge>> E(node_n + 1);
    REP(i, edge_n) {
      int from, to, cost, time, campany;
      cin >> from >> to >> cost >> time >> campany;
      E[from].push_back({to, cost, time, 1 << campany});
      E[to].push_back({from, cost, time, 1 << campany});
    }
    int start, goal, passport_n;
    cin >> start >> goal >> passport_n;
    vector<Passport> pass(passport_n);
    REP(i, passport_n) {
      int camp_n;
      cin >> camp_n;
      cin >> pass[i].cost;
      REP(j, camp_n) {
        int camp;
        cin >> camp;
        pass[i].campany |= (1 << camp);
      }
    }

    int res = INF;
    LOG("bbbbbbbbb\\n");
    REP(i, 1 << passport_n) {
      LOG("aaaaaaaaaaaaaa\\n");
      fill_n((int *)G, 25 * 101, INF);
      G[start][0] = 0;
      int free_campany = 0;
      REP(j, passport_n) {
        if (i & 1 << j) {
          G[start][0] += pass[j].cost;
          free_campany |= pass[j].campany;
        }
      }

      priority_queue<P, vector<P>, greater<P>> que;
      que.push({start, G[start][0], 0});
      while (!que.empty()) {
        P p = que.top();
        que.pop();
        LOG(">>> p:%d  cpst:%d\\n", p.p, p.cost);
        if (p.p == goal) {
          res = min(res, p.cost);
          break;
        }

        for (Edge e : E[p.p]) {
          LOG(" -- %d\\n", e.to);
          int next_cost = p.cost + e.cost;
          if (e.campany & free_campany)
            next_cost -= e.cost;
          int next_time = p.time + e.time;
          if (next_time > max_time)
            continue;
          if (G[e.to][next_time] > next_cost) {
            G[e.to][next_time] = next_cost;
            LOG("p %d  cost:%d\\n", e.to, next_cost);
            que.push({e.to, next_cost, next_time});
          }
        }
      }
    }

    if (res == INF) {
      cout << -1 << endl;
    } else {
      cout << res << endl;
    }
  }
}