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

#include <cmath>
#include <iostream>
#include <map>
#include <vector>

#define show(x) cerr << #x << " = " << x << endl

using namespace std;
using ld = long double;
using ll = long long;
constexpr ld PI = 3.1415926535898;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "sz:" << v.size() << "\\n[";
  for (const auto &p : v) {
    os << p << ",";
  }
  os << "]\\n";
  return os;
}
template <typename S, typename T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}

struct Pos {
  ld x;
  ld y;
  Pos operator-(const Pos &p) const { return Pos{x - p.x, y - p.y}; }
};

ld distance(const Pos &p1, const Pos &p2) {
  return hypot(p1.x - p2.x, p1.y - p2.y);
}

ld dot(const Pos &p1, const Pos &p2) { return p1.x * p2.x + p1.y * p2.y; }

bool reachable(const Pos &prev, const Pos &now, const Pos &to, const ld theta) {
  if (theta == 180) {
    return true;
  } else {
    return dot(now - prev, to - now) >
           distance(now, prev) * distance(to, now) * cos(theta / 180.0 * PI);
  }
}

int main() {
  int n;
  cin >> n;
  ld r, theta;
  cin >> r >> theta;

  vector<Pos> pos(n);
  for (int i = 0; i < n; i++) {
    cin >> pos[i].x >> pos[i].y;
  }

  vector<vector<ld>> d(n, vector<ld>(n, 0));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      d[i][j] = distance(pos[i], pos[j]);
    }
  }

  vector<vector<vector<int>>> route(
      n, vector<vector<int>>(n, vector<int>(0))); // prev->now???????????????to
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        if (k == j) {
          continue;
        }
        if (reachable(pos[i], pos[j], pos[k], theta)) {
          route[i][j].push_back(k);
        }
      }
    }
  }

  // for (int i = 0; i < n; i++) {
  //     for (int j = 0; j < n; j++) {
  //         if (not route[i][j].empty()) {
  //             cerr << "## After(" << i << "->" << j << ")##\\n[";
  //             for (const int to : route[i][j]) {
  //                 cerr << to << ",";
  //             }
  //             cerr << "]" << endl;
  //         }
  //     }
  // }

  constexpr ld INF = 100000;
  vector<vector<ld>> prev(n, vector<ld>(n, INF));
  vector<vector<ld>> dp(n, vector<ld>(n, INF));
  for (int i = 1; i < n; i++) {
    if (d[0][i] <= r) {
      prev[0][i] = d[0][i];
    }
  }
  for (int i = 0; i < 2 * r; i++) {
    int num = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (prev[i][j] != INF) {
          num++;
          for (const int to : route[i][j]) {
            const ld l = prev[i][j] + d[j][to];
            if (l > r) {
              continue;
            }
            dp[j][to] = min(dp[j][to], l);
          }
        }
      }
    }
    if (num == 0) {
      cout << i << endl;
      return 0;
    }
    prev = dp;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        dp[i][j] = INF;
      }
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <iostream>
#include <map>
#include <vector>

#define show(x) cerr << #x << " = " << x << endl

using namespace std;
using ld = long double;
using ll = long long;
constexpr ld PI = 3.1415926535898;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "sz:" << v.size() << "\\n[";
  for (const auto &p : v) {
    os << p << ",";
  }
  os << "]\\n";
  return os;
}
template <typename S, typename T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}

struct Pos {
  ld x;
  ld y;
  Pos operator-(const Pos &p) const { return Pos{x - p.x, y - p.y}; }
};

ld distance(const Pos &p1, const Pos &p2) {
  return hypot(p1.x - p2.x, p1.y - p2.y);
}

ld dot(const Pos &p1, const Pos &p2) { return p1.x * p2.x + p1.y * p2.y; }

bool reachable(const Pos &prev, const Pos &now, const Pos &to, const ld theta) {
  if (theta == 180) {
    return true;
  } else {
    return dot(now - prev, to - now) >
           distance(now, prev) * distance(to, now) * cos(theta / 180.0 * PI);
  }
}

int main() {
  int n;
  cin >> n;
  ld r, theta;
  cin >> r >> theta;

  vector<Pos> pos(n);
  for (int i = 0; i < n; i++) {
    cin >> pos[i].x >> pos[i].y;
  }

  vector<vector<ld>> d(n, vector<ld>(n, 0));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      d[i][j] = distance(pos[i], pos[j]);
    }
  }

  vector<vector<vector<int>>> route(
      n, vector<vector<int>>(n, vector<int>(0))); // prev->now???????????????to
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        if (k == j) {
          continue;
        }
        if (reachable(pos[i], pos[j], pos[k], theta)) {
          route[i][j].push_back(k);
        }
      }
    }
  }

  // for (int i = 0; i < n; i++) {
  //     for (int j = 0; j < n; j++) {
  //         if (not route[i][j].empty()) {
  //             cerr << "## After(" << i << "->" << j << ")##\\n[";
  //             for (const int to : route[i][j]) {
  //                 cerr << to << ",";
  //             }
  //             cerr << "]" << endl;
  //         }
  //     }
  // }

  map<pair<int, int>, ld> prev;
  map<pair<int, int>, ld> dp;
  for (int i = 1; i < n; i++) {
    if (d[0][i] <= r) {
      prev[make_pair(0, i)] = d[0][i];
    }
  }
  for (int i = 0; i < 2 * r; i++) {
    if (prev.empty()) {
      cout << i << endl;
      return 0;
    }
    for (const auto &p : prev) {
      const int from = p.first.first;
      const int now = p.first.second;
      const ld length = p.second;
      for (const int to : route[from][now]) {
        const ld tot = length + d[now][to];
        if (tot > r) {
          continue;
        }
        const auto e = make_pair(now, to);
        if (dp.find(e) == dp.end()) {
          dp[e] = tot;
        } else {
          dp[e] = min(dp[e], tot);
        }
      }
    }
    // cerr << "dp = [";
    // for (const auto& e : dp) {
    //     cerr << e << ",";
    // }
    // cerr << "]" << endl;

    prev = dp;
    dp.clear();
  }

  return 0;
}