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

#include <bits/stdc++.h>
using namespace std;

#define BIG_NUM 2000000000

struct Info {
  Info(int arg_node_id, int arg_state, int arg_num_okarina, int arg_num_day,
       int arg_total_move) {
    node_id = arg_node_id;
    state = arg_state;
    num_okarina = arg_num_okarina;
    num_day = arg_num_day;
    total_move = arg_total_move;
  }
  bool operator<(const struct Info &arg) const {
    return (num_okarina + total_move) > (arg.num_okarina + arg.total_move);
  }

  int node_id, state, num_okarina, num_day, total_move;
};

struct Data {
  Data(int arg_to, int arg_need_state) {
    to = arg_to;
    need_state = arg_need_state;
  }
  int to, need_state;
};

int POW[5] = {1, 2, 4, 8, 16};
int min_cost[100][16][101];

int main() {

  int N, M, E, start, goal, R;
  scanf("%d %d %d %d %d %d", &N, &M, &E, &start, &goal, &R);

  if (R == 0) {
    printf("-1\\n");
    return 0;
  }

  vector<Data> V[N];

  int from, to;

  for (int i = 0; i < M; i++) {
    scanf("%d %d", &from, &to);
    V[from].push_back(Data(to, 0));
    V[to].push_back(Data(from, 0));
  }

  int town, event[N];
  for (int i = 0; i < N; i++)
    event[i] = 0;

  for (int i = 0; i < E; i++) {
    scanf("%d %d %d", &from, &to, &town);
    event[town] = POW[i];
    V[from].push_back(Data(to, POW[i]));
    V[to].push_back(Data(from, POW[i]));
  }

  int ans = BIG_NUM;

  for (int town = 0; town < N; town++) {
    for (int state = 0; state < POW[E]; state++) {
      for (int day = 0; day <= R; day++)
        min_cost[town][state][day] = BIG_NUM;
    }
  }

  priority_queue<Info> Q;

  if (event[start] == 0) {
    min_cost[start][0][0] = 0;
    Q.push(Info(start, 0, 0, 0, 0));
  } else {
    min_cost[start][event[start]][0] = 0;
    Q.push(Info(start, event[start], 0, 0, 0));
  }

  int next_town, next_state;

  while (!Q.empty()) {

    if (Q.top().node_id == goal) {
      ans = min(ans, Q.top().num_okarina + Q.top().total_move);
      Q.pop();
    } else if (Q.top().num_okarina + Q.top().total_move >
                   min_cost[Q.top().node_id][Q.top().state][Q.top().num_day] ||
               Q.top().num_okarina + Q.top().total_move >= ans) {
      Q.pop();
    } else {

      if (min_cost[start][Q.top().state][0] >
          (Q.top().num_okarina + 1) + Q.top().total_move) {
        min_cost[start][Q.top().state][0] =
            (Q.top().num_okarina + 1) + Q.top().total_move;
        Q.push(Info(start, Q.top().state, Q.top().num_okarina + 1, 0,
                    Q.top().total_move));
      }

      if (Q.top().num_day == R) {
        Q.pop();
        continue;
      }

      for (int i = 0; i < V[Q.top().node_id].size(); i++) {

        if (V[Q.top().node_id][i].need_state == 0) {
          next_town = V[Q.top().node_id][i].to;
          next_state = (Q.top().state | event[next_town]);

          if (min_cost[next_town][next_state][Q.top().num_day + 1] >
              Q.top().num_okarina + Q.top().total_move + 1) {
            min_cost[next_town][next_state][Q.top().num_day + 1] =
                Q.top().num_okarina + Q.top().total_move + 1;
            Q.push(Info(next_town, next_state, Q.top().num_okarina,
                        Q.top().num_day + 1, Q.top().total_move + 1));
          }
        } else {
          if ((Q.top().state & V[Q.top().node_id][i].need_state) == 0) {
            continue;
          }
          next_town = V[Q.top().node_id][i].to;
          next_state = (Q.top().state | event[next_town]);

          if (min_cost[next_town][next_state][Q.top().num_day + 1] >
              Q.top().num_okarina + Q.top().total_move + 1) {
            min_cost[next_town][next_state][Q.top().num_day + 1] =
                Q.top().num_okarina + Q.top().total_move + 1;
            Q.push(Info(next_town, next_state, Q.top().num_okarina,
                        Q.top().num_day + 1, Q.top().total_move + 1));
          }
        }
      }

      Q.pop();
    }
  }

  if (ans == BIG_NUM) {
    printf("-1\\n");
  } else {
    printf("%d\\n", ans);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define BIG_NUM 2000000000

struct Info {
  Info(int arg_node_id, int arg_state, int arg_num_okarina, int arg_num_day,
       int arg_total_move) {
    node_id = arg_node_id;
    state = arg_state;
    num_okarina = arg_num_okarina;
    num_day = arg_num_day;
    total_move = arg_total_move;
  }
  bool operator<(const struct Info &arg) const {
    return (num_okarina + total_move) > (arg.num_okarina + arg.total_move);
  }

  int node_id, state, num_okarina, num_day, total_move;
};

struct Data {
  Data(int arg_to, int arg_need_state) {
    to = arg_to;
    need_state = arg_need_state;
  }
  int to, need_state;
};

int POW[5] = {1, 2, 4, 8, 16};

int main() {

  int N, M, E, start, goal, R;
  scanf("%d %d %d %d %d %d", &N, &M, &E, &start, &goal, &R);

  if (R == 0) {
    printf("-1\\n");
    return 0;
  }

  vector<Data> V[N];

  int from, to;

  for (int i = 0; i < M; i++) {
    scanf("%d %d", &from, &to);
    V[from].push_back(Data(to, 0));
    V[to].push_back(Data(from, 0));
  }

  int town, event[N];
  for (int i = 0; i < N; i++)
    event[i] = 0;

  for (int i = 0; i < E; i++) {
    scanf("%d %d %d", &from, &to, &town);
    event[town] = POW[i];
    V[from].push_back(Data(to, POW[i]));
    V[to].push_back(Data(from, POW[i]));
  }

  int ans = BIG_NUM;

  int min_cost[N][POW[E]];

  for (int town = 0; town < N; town++) {
    for (int state = 0; state < POW[E]; state++)
      min_cost[town][state] = BIG_NUM;
  }

  priority_queue<Info> Q;

  if (event[start] == 0) {
    min_cost[start][0] = 0;
    Q.push(Info(start, 0, 0, 0, 0));
  } else {
    min_cost[start][event[start]] = 0;
    Q.push(Info(start, event[start], 0, 0, 0));
  }

  int next_town, next_state;

  while (!Q.empty()) {

    if (Q.top().node_id == goal) {
      ans = min(ans, Q.top().num_okarina + Q.top().total_move);
      Q.pop();
    } else if (Q.top().num_okarina + Q.top().total_move >
               min_cost[Q.top().node_id][Q.top().state]) {
      Q.pop();
    } else {

      if (min_cost[start][Q.top().state] >
          (Q.top().num_okarina + 1) + Q.top().total_move) {
        min_cost[start][Q.top().state] =
            (Q.top().num_okarina + 1) + Q.top().total_move;
        Q.push(Info(start, Q.top().state, Q.top().num_okarina + 1, 0,
                    Q.top().total_move));
      }

      if (Q.top().num_day == R) {
        continue;
      }

      for (int i = 0; i < V[Q.top().node_id].size(); i++) {
        if (V[Q.top().node_id][i].need_state == 0) {
          next_town = V[Q.top().node_id][i].to;
          next_state = (Q.top().state | event[next_town]);

          if (min_cost[next_town][next_state] >
              Q.top().num_okarina + Q.top().total_move + 1) {
            min_cost[next_town][next_state] =
                Q.top().num_okarina + Q.top().total_move + 1;
            Q.push(Info(next_town, next_state, Q.top().num_okarina,
                        Q.top().num_day + 1, Q.top().total_move + 1));
          }
        } else {
          if ((Q.top().state & V[Q.top().node_id][i].need_state) == 0)
            continue;

          next_town = V[Q.top().node_id][i].to;
          next_state = (Q.top().state | event[next_town]);

          if (min_cost[next_town][next_state] >
              Q.top().num_okarina + Q.top().total_move + 1) {
            min_cost[next_town][next_state] =
                Q.top().num_okarina + Q.top().total_move + 1;
            Q.push(Info(next_town, next_state, Q.top().num_okarina,
                        Q.top().num_day + 1, Q.top().total_move + 1));
          }
        }
      }

      Q.pop();
    }
  }

  if (ans == BIG_NUM) {
    printf("-1\\n");
  } else {
    printf("%d\\n", ans);
  }

  return 0;
}