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

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#undef max
#undef min

struct Node {
  int lastPos = 0;
  int pos = 0;
  int carrot = 0;
  float len = 0;

  bool operator<(const Node &rhs) const {
    if (len == rhs.len)
      return carrot > rhs.carrot;
    return len < rhs.len;
  }
  bool operator>(const Node &rhs) const {
    if (len == rhs.len)
      return carrot < rhs.carrot;
    return len > rhs.len;
  }
};

int main() {
  int n;
  float r, theta;
  float angleTable[20][20][20] = {0};
  float dist[20][20] = {0};
  std::vector<float> memo[20][20];
  std::vector<std::pair<int, int>> city;
  std::cin >> n >> r >> theta;
  theta /= 180.f;
  theta *= M_PI;
  for (int i = 0; i < n; i++) {
    int x, y;
    std::cin >> x >> y;
    city.push_back(std::make_pair(x, y));
  }

  // memo初期化
  for (auto &x : memo) {
    for (auto &y : x) {
      y.push_back(0.f);
    }
  }

  // 都市間移動の角度と距離を計算
  for (int i = 0; i < city.size(); i++) {   // 前
    for (int j = 0; j < city.size(); j++) { // 今
      if (i == j)
        continue;
      for (int k = 0; k < city.size(); k++) { // 次
        if (j == k)
          continue;
        if (i != k) {
          float vx[2] = {(float)(city[i].first - city[j].first),
                         (float)(city[k].first - city[j].first)};
          float vy[2] = {(float)(city[i].second - city[j].second),
                         (float)(city[k].second - city[j].second)};
          float jLen = std::sqrt(vx[0] * vx[0] + vy[0] * vy[0]);
          float kLen = std::sqrt(vx[1] * vx[1] + vy[1] * vy[1]);
          float dot = vx[0] * vx[1] + vy[0] * vy[1];
          float a = dot / (jLen * kLen);
          angleTable[i][j][k] = (float)(M_PI)-std::acos(dot / (jLen * kLen));
        } else
          angleTable[i][j][k] = (float)(M_PI);
      }
      float vx = (float)city[j].first - city[i].first;
      float vy = (float)city[j].second - city[i].second;
      dist[i][j] = std::sqrt(vx * vx + vy * vy);
    }
  }

  std::priority_queue<Node, std::vector<Node>, std::greater<>> s;
  int maxCarrot = 0;
  s.push({0, 0, 0, 0.f});

  while (!s.empty()) {
    auto node = s.top();
    s.pop();
    for (int i = 0; i < city.size(); i++) {
      if (i == node.pos)
        continue;
      if (node.pos != node.lastPos &&
          angleTable[node.lastPos][node.pos][i] >= theta)
        continue;
      auto next = node;
      next.len += dist[node.pos][i];
      if (next.len > r)
        continue;

      next.lastPos = next.pos;
      next.pos = i;
      next.carrot++;

      if (memo[next.lastPos][i].size() <= next.carrot) {
        int m = memo[next.lastPos][i].size();
        for (int j = 0; j < next.carrot - m + 1; j++) {
          memo[next.lastPos][i].push_back(next.len);
        }
      } else {
        if (memo[next.lastPos][i][next.carrot] <= next.len)
          continue; // もっと短い距離で同数の人参に到達
      }
      memo[next.lastPos][i][next.carrot] = next.len;
      maxCarrot = std::max(maxCarrot, next.carrot);
      s.push(next);
    }
  }
  std::cout << maxCarrot << std::endl;
  return 0;
}


Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#undef max
#undef min

struct Node {
  int lastPos = 0;
  int pos = 0;
  int carrot = 0;
  float len = 0;
  std::vector<int> hist;

  bool operator<(const Node &rhs) const {
    if (len == rhs.len)
      return carrot > rhs.carrot;
    return len < rhs.len;
  }
  bool operator>(const Node &rhs) const {
    if (len == rhs.len)
      return carrot < rhs.carrot;
    return len > rhs.len;
  }
};

int main() {
  int n;
  float r, theta;
  float angleTable[20][20][20] = {0};
  float dist[20][20] = {0};
  std::vector<float> memo[20];
  std::vector<std::pair<int, int>> city;
  std::cin >> n >> r >> theta;
  theta /= 180.f;
  theta *= M_PI;
  for (int i = 0; i < n; i++) {
    int x, y;
    std::cin >> x >> y;
    city.push_back(std::make_pair(x, y));
  }

  // memo初期化
  for (auto &x : memo) {
    x.push_back(0.f);
  }

  // 都市間移動の角度と距離を計算
  for (int i = 0; i < city.size(); i++) {   // 前
    for (int j = 0; j < city.size(); j++) { // 今
      if (i == j)
        continue;
      for (int k = 0; k < city.size(); k++) { // 次
        if (j == k)
          continue;
        if (i != k) {
          float vx[2] = {(float)(city[i].first - city[j].first),
                         (float)(city[k].first - city[j].first)};
          float vy[2] = {(float)(city[i].second - city[j].second),
                         (float)(city[k].second - city[j].second)};
          float jLen = std::sqrt(vx[0] * vx[0] + vy[0] * vy[0]);
          float kLen = std::sqrt(vx[1] * vx[1] + vy[1] * vy[1]);
          float dot = vx[0] * vx[1] + vy[0] * vy[1];
          float a = dot / (jLen * kLen);
          angleTable[i][j][k] = (float)(M_PI)-std::acos(dot / (jLen * kLen));
        } else
          angleTable[i][j][k] = (float)(M_PI);
      }
      float vx = (float)city[j].first - city[i].first;
      float vy = (float)city[j].second - city[i].second;
      dist[i][j] = std::sqrt(vx * vx + vy * vy);
    }
  }

  std::priority_queue<Node> s;
  int maxCarrot = 0;
  s.push({0, 0, 0, 0.f});

  while (!s.empty()) {
    auto node = s.top();
    s.pop();
    for (int i = 0; i < city.size(); i++) {
      if (i == node.pos)
        continue;
      if (node.pos != node.lastPos &&
          angleTable[node.lastPos][node.pos][i] >= theta)
        continue;
      auto next = node;
      next.lastPos = next.pos;
      next.len += dist[node.pos][i];
      if (next.len > r)
        continue;

      next.pos = i;
      next.carrot++;

      if (memo[i].size() <= next.carrot) {
        int m = memo[i].size();
        for (int j = 0; j < next.carrot - m + 1; j++) {
          memo[i].push_back(next.len);
        }
      } else {
        if (memo[i][next.carrot] <= next.len)
          continue; // もっと短い距離で同数の人参に到達
      }
      memo[i][next.carrot] = next.len;
      next.hist.push_back(i);
      maxCarrot = std::max(maxCarrot, next.carrot);
      s.push(next);
    }
  }
  std::cout << maxCarrot << std::endl;
  return 0;
}