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

#include <bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 500

struct Info {
  ll left, right;
};

ll min_dist[NUM][NUM];
ll year_sum[NUM];
int start_planet;
bool visited[NUM];
vector<int> G[NUM];
Info info[NUM];

int main() {

  int N;

  scanf("%d %d", &N, &start_planet);
  start_planet--;

  for (int i = 0; i < N; i++) {
    scanf("%d %d", &info[i].left, &info[i].right);
  }

  for (int from = 0; from < N; from++) {
    for (int to = 0; to < N; to++) {
      scanf("%lld", &min_dist[from][to]);
    }
  }

  // 全点対間最短経路を求める
  for (int mid = 0; mid < N; mid++) {
    for (int start = 0; start < N; start++) {
      for (int goal = 0; goal < N; goal++) {
        min_dist[start][goal] = min(min_dist[start][goal],
                                    min_dist[start][mid] + min_dist[mid][goal]);
      }
    }
  }

  ll ans = 0;

  for (int i = 0; i < N; i++) {
    if (info[i].right >= min_dist[start_planet][i]) {
      year_sum[i] =
          info[i].right - max(info[i].left, min_dist[start_planet][i]);
      visited[i] = true;
    } else {
      visited[i] = false;
    }
  }

  for (int a = 0; a < N; a++) {
    for (int i = 0; i < N; i++) {
      for (int k = 0; k < N; k++) {
        if (visited[i] == true &&
            info[k].right >= info[i].right + min_dist[i][k]) {
          year_sum[k] =
              max(year_sum[k],
                  info[k].right -
                      max(info[k].left, info[i].right + min_dist[i][k]) +
                      year_sum[i]);

          visited[k] = true;
          ans = max(ans, year_sum[k]);
        }
      }
    }
  }

  printf("%lld\\n", ans);

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 500

struct Info {
  ll left, right;
};

struct Data {
  Data() {
    node_id = 0;
    sum_year = 0;
  }

  Data(int arg_node_id, ll arg_sum_year) {
    node_id = arg_node_id;
    sum_year = arg_sum_year;
  }
  bool operator<(const struct Data &arg) const { // 総年数の降順(PQ)
    return sum_year < arg.sum_year;
  }

  int node_id;
  ll sum_year;
};

ll min_dist[NUM][NUM];
ll year_sum[NUM];
int start_planet;
vector<int> G[NUM];
Info info[NUM];

int main() {

  int N;

  scanf("%d %d", &N, &start_planet);
  start_planet--;

  for (int i = 0; i < N; i++) {
    scanf("%d %d", &info[i].left, &info[i].right);
  }

  for (int from = 0; from < N; from++) {
    for (int to = 0; to < N; to++) {
      scanf("%lld", &min_dist[from][to]);
    }
  }

  // 全点対間最短経路を求める
  for (int mid = 0; mid < N; mid++) {
    for (int start = 0; start < N; start++) {
      for (int goal = 0; goal < N; goal++) {
        min_dist[start][goal] = min(min_dist[start][goal],
                                    min_dist[start][mid] + min_dist[mid][goal]);
      }
    }
  }

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < N; k++) {
      if (k == i)
        continue;
      if (info[k].right >=
          info[i].right +
              min_dist[i][k]) { // iからkに行っても、加算期間に間に合う場合
        G[i].push_back(k);
      }
    }
  }

  for (int i = 0; i < N; i++)
    year_sum[i] = 0;

  year_sum[start_planet] = 0;
  ll ans = info[start_planet].right - info[start_planet].left;

  int next_node;
  ll next_value;
  priority_queue<Data> Q;

  // ★★最初の星は、すぐ出発するか、rightまで滞在するかの2択★★

  // 最初の星からいきなり出発する場合
  for (int i = 0; i < N; i++) {
    if (i == start_planet)
      continue;

    if (info[i].right >= min_dist[start_planet][i]) {
      year_sum[i] =
          info[i].right - max(info[i].left, min_dist[start_planet][i]);
      ans = max(ans, year_sum[i]);
      Q.push(Data(i, year_sum[i]));
    }
  }

  // 最初の星でrightまで滞在する場合
  for (int i = 0; i < G[start_planet].size(); i++) {
    next_node = G[start_planet][i];
    next_value =
        (info[start_planet].right - info[start_planet].left) +
        info[next_node].right -
        max(info[next_node].left,
            info[start_planet].right + min_dist[start_planet][next_node]);
    if (year_sum[next_node] >= next_value)
      continue;
    year_sum[next_node] = next_value;
    ans = max(ans, next_value);
    Q.push(Data(next_node, next_value));
  }

  Data tmp;

  while (!Q.empty()) {

    tmp = Q.top(); // ★PQは降順なので、先にpopする★
    Q.pop();

    if (tmp.sum_year < year_sum[tmp.node_id]) {
      // Do nothing
    } else {

      for (int i = 0; i < G[tmp.node_id].size(); i++) {
        next_node = G[tmp.node_id][i];
        next_value =
            tmp.sum_year + info[next_node].right -
            max(info[next_node].left,
                info[tmp.node_id].right + min_dist[tmp.node_id][next_node]);

        if (year_sum[next_node] < next_value) {
          year_sum[next_node] = next_value;
          ans = max(ans, next_value);
          Q.push(Data(next_node, next_value));
        }
      }
    }
  }

  printf("%lld\\n", ans);

  return 0;
}