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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define itrep(type, it, t)                                                     \\
  for (type::iterator it = t.begin(); it != t.end(); it++)
using namespace std;

#define MAX_N (2001)
#define MAX_DIST (20000)

struct edge {
  int to;
  int cost;
};

typedef pair<int, int> P; // first: 最短距離, second: 頂点番号

vector<edge> G[MAX_N]; // 隣接リスト表現

int d[MAX_N];   // 始点sから各頂点への距離
int cnt[MAX_N]; // 始点への最短経路の数
void dijkstra(int s) {
  fill(d, d + MAX_N, MAX_N);
  d[s] = 0; // 始点sへの最短距離は0

  fill(cnt, cnt + MAX_N, 0);
  cnt[s] = 1; // 始点sへの最短経路数は1

  priority_queue<P, vector<P>, greater<P>>
      que; // 距離が小さい順に取り出せるようgreater<P>を指定
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second; // 更新した頂点の中で距離が最小の頂点v
    if (d[v] < p.first) {
      continue;
    }
    for (auto e : G[v]) { // 頂点vから出る辺eを走査
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
        cnt[e.to] =
            cnt[v]; // コストが更新された場合は直前の頂点への最短経路数で上書き
      } else if (d[e.to] == d[v] + e.cost) {
        cnt[e.to] +=
            cnt[v]; // コストが一致する場合はこれまでの最短経路数を足し合わせ
      }
    }
  }
}

int main(void) {

  int N, X, Y;
  cin >> N >> X >> Y;

  for (int i = 1; i < N; i++) {
    edge e1, e2;
    e1.to = i + 1;
    e2.to = i;
    e1.cost = e2.cost = 1;
    G[i].push_back(e1);
    G[i + 1].push_back(e2);
  }
  {
    edge e1, e2;
    e1.to = Y;
    e2.to = X;
    e1.cost = e2.cost = 1;
    G[X].push_back(e1);
    G[Y].push_back(e2);
  }

  int ans[MAX_N];
  fill(ans, ans + MAX_N, 0);
  for (int i = 1; i <= N; i++) {
    dijkstra(i);
    rep(j, N + 1) ans[d[j]]++;
  }

  for (int i = 1; i < N; i++) {
    cout << (ans[i] / 2) << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define itrep(type, it, t)                                                     \\
  for (type::iterator it = t.begin(); it != t.end(); it++)
using namespace std;

#define MAX_N (2001)
#define MAX_DIST (20000)

struct edge {
  int to;
  int cost;
};

typedef pair<int, int> P; // first: 最短距離, second: 頂点番号

vector<edge> G[MAX_N]; // 隣接リスト表現

int d[MAX_N];   // 始点sから各頂点への距離
int cnt[MAX_N]; // 始点への最短経路の数
void dijkstra(int s) {
  fill(d, d + MAX_N, MAX_N);
  d[s] = 0; // 始点sへの最短距離は0

  fill(cnt, cnt + MAX_N, 0);
  cnt[s] = 1; // 始点sへの最短経路数は1

  priority_queue<P, vector<P>, greater<P>>
      que; // 距離が小さい順に取り出せるようgreater<P>を指定
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second; // 更新した頂点の中で距離が最小の頂点v
    if (d[v] < p.first) {
      continue;
    }
    cerr << "--- " << v << " ---" << endl;
    for (auto e : G[v]) { // 頂点vから出る辺eを走査
      cerr << "(" << e.to << " " << e.cost << ")" << endl;
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
        cnt[e.to] =
            cnt[v]; // コストが更新された場合は直前の頂点への最短経路数で上書き
      } else if (d[e.to] == d[v] + e.cost) {
        cnt[e.to] +=
            cnt[v]; // コストが一致する場合はこれまでの最短経路数を足し合わせ
      }
    }
    cerr << "- d[i] -" << endl;
    for (int i = 1; i <= 5; i++) {
      cerr << d[i] << endl;
    }
    cerr << "- cnt[i] -" << endl;
    for (int i = 1; i <= 5; i++) {
      cerr << cnt[i] << endl;
    }
    cerr << "-----" << endl;
  }
}

int main(void) {

  int N, X, Y;
  cin >> N >> X >> Y;

  for (int i = 1; i < N; i++) {
    edge e1, e2;
    e1.to = i + 1;
    e2.to = i;
    e1.cost = e2.cost = 1;
    G[i].push_back(e1);
    G[i + 1].push_back(e2);
  }
  {
    edge e1, e2;
    e1.to = Y;
    e2.to = X;
    e1.cost = e2.cost = 1;
    G[X].push_back(e1);
    G[Y].push_back(e2);
    for (auto e : G[X]) { // 頂点vから出る辺eを走査
      cerr << "(" << e.to << " " << e.cost << ")" << endl;
    }
  }
  for (auto e : G[X]) { // 頂点vから出る辺eを走査
    cerr << "(" << e.to << " " << e.cost << ")" << endl;
  }

  int ans[MAX_N];
  fill(ans, ans + MAX_N, 0);
  for (int i = 1; i <= N; i++) {
    dijkstra(i);
    rep(j, N + 1) ans[d[j]]++;
    cerr << "-- ans --" << endl;
    rep(j, N + 1) cerr << ans[j] << endl;
    cerr << "---------" << endl;
  }

  for (int i = 1; i < N; i++) {
    cout << (ans[i] / 2) << endl;
  }

  return 0;
}