Problem p00888 (C++) — buggy submission, verdict: Runtime Error

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

vector<pair<ld, int>> ps;

ld getdis(pair<ld, int> &f, pair<ld, int> &t) {
  return sqrt((f.first - t.first) * (f.first - t.first) +
              (f.second - t.second) * (f.second - t.second));
}
ld getdis(int from, int to) { return getdis(ps[from], ps[to]); }

struct aa {
  int a;
  int b;
  ld time;
};
class Compare {
public:
  // aa?????????????????¶
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};

vector<int> getsta(const int now) {
  vector<int> sta;
  {

    int s;
    if (now == 0)
      s = -1;
    else if (ps[now - 1].second < ps[now].second)
      s = 0;
    else if (ps[now - 1].second == ps[now].second)
      s = 1;
    else
      s = 2;
    sta.push_back(s);
  }
  sta.push_back(1);
  {

    int s;
    if (now == ps.size() - 1)
      s = -1;
    else if (ps[now + 1].second < ps[now].second)
      s = 0;
    else if (ps[now + 1].second == ps[now].second)
      s = 1;
    else
      s = 2;
    sta.push_back(s);
  }
  return sta;
}
int main() {
  while (1) {
    int N;
    cin >> N;
    if (!N)
      break;
    ps.clear();
    {
      set<int> ys;
      vector<pair<ld, int>> or_ps;
      for (int i = 0; i < N; ++i) {
        int x, y;
        cin >> x >> y;
        or_ps.emplace_back(x, y);
        ys.emplace(y);
      }
      for (int i = 0; i < N - 1; ++i) {
        ps.emplace_back(or_ps[i]);
        for (auto y : ys) {
          if ((or_ps[i].second < y && y < or_ps[i + 1].second) ||
              (or_ps[i + 1].second < y && y < or_ps[i].second)) {
            ld x =
                or_ps[i].first + (or_ps[i + 1].first - or_ps[i].first) *
                                     (ld(y - or_ps[i].second) /
                                      (or_ps[i + 1].second - or_ps[i].second));
            ps.emplace_back(ld(x), y);
          }
        }
      }
      ps.emplace_back(or_ps[N - 1]);
      sort(ps.begin(), ps.end());
    }
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{0, int(ps.size()) - 1, 0});
    map<pair<int, int>, ld> memo;
    memo[make_pair(0, ps.size() - 1)] = 0;
    ld ans = 0;
    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      const int nowa = atop.a;
      const int nowb = atop.b;
      const ld nowtime = atop.time;
      if (nowa == nowb) {
        ans = nowtime;
        break;
      }
      vector<int> astatus, bstatus;
      astatus = getsta(nowa);
      bstatus = getsta(nowb);
      for (int i = 0; i < 3; ++i) {
        if (astatus[i] == -1)
          continue;
        for (int j = 0; j < 3; ++j) {
          if (bstatus[j] == -1)
            continue;
          if (astatus[i] == bstatus[j]) {
            const int nexta = nowa + i - 1;
            const int nextb = nowb + j - 1;
            const ld nexttime =
                nowtime + getdis(nowa, nexta) + getdis(nowb, nextb);
            auto it = memo.find(make_pair(nexta, nextb));
            if (it == memo.end() || it->second > nexttime + eps) {
              memo[make_pair(nexta, nextb)] = nexttime;
              que.push(aa{nexta, nextb, nexttime});
            }
          }
        }
      }
    }
    cout << fixed << setprecision(22) << ans << endl;
  }
  return 0;
}

Error: WA

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = float;
template <class T> using Table = vector<vector<T>>;

const ld eps = 1e-9;
struct aa {
  int l;
  int r;
  ld time;
};
class Compare {
public:
  // aa?????????????????¶
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};
ld gettime(vector<pair<ld, int>> &ps, int from, int to) {
  if (from > to)
    swap(from, to);
  else if (from == to)
    return 0;
  pair<ld, int> f(ps[from]);
  pair<ld, int> t(ps[from + 1]);
  return sqrt((f.first - t.first) * (f.first - t.first) +
              (f.second - t.second) * (f.second - t.second));
}

vector<vector<ld>> dp(3998);
int main() {
  for (int i = 0; i < dp.size(); ++i) {
    dp[i].resize(i + 2);
  }
  while (1) {
    int N;
    cin >> N;
    if (!N)
      break;
    vector<pair<int, int>> coors;
    set<int> ys;
    for (int i = 0; i < N; ++i) {
      int x, y;
      cin >> x >> y;
      coors.emplace_back(x, y);
      ys.emplace(y);
    }
    vector<pair<ld, int>> nodes;
    for (int i = 0; i < N - 1; ++i) {
      for (auto y : ys) {

        if ((coors[i].second + eps < y && y < coors[i + 1].second - eps) ||
            (coors[i].second - eps > y && coors[i + 1].second + eps < y)) {
          nodes.emplace_back(coors[i].first +
                                 ld(coors[i + 1].first - coors[i].first) *
                                     ld(y - coors[i].second) /
                                     ld(coors[i + 1].second - coors[i].second),
                             (y));
        }
      }
    }
    for (int i = 0; i < N; ++i) {
      nodes.emplace_back(ld(coors[i].first), (coors[i].second));
    }
    sort(nodes.begin(), nodes.end());

    const int start = 0;
    const int goal = nodes.size() - 1;

    for (int i = 0; i < nodes.size(); ++i) {
      for (int j = 0; j < i + 2; ++j) {
        dp[i][j] = 1e9;
      }
    }
    dp[0][goal] = 0;
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{0, goal, 0});
    ld ans = 1e9;
    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      int nowl = atop.l;
      int nowr = atop.r;
      ld nowtime = atop.time;
      if (nowl == nowr) {
        ans = nowtime;
        break;
      } else if (nowl + 1 == nowr) {
        ans = nowtime + gettime(nodes, nowl, nowr);
        break;
      }

      bool lldown = nowl && nodes[nowl - 1].second < nodes[nowl].second;
      bool llup = nowl && nodes[nowl - 1].second > nodes[nowl].second;
      bool lrdown = nodes[nowl].second > nodes[nowl + 1].second;
      bool lrup = nodes[nowl].second < nodes[nowl + 1].second;
      bool rldown = nodes[nowr - 1].second < nodes[nowr].second;
      bool rlup = nodes[nowr - 1].second > nodes[nowr].second;
      bool rrdown = nowr < nodes.size() - 1 &&
                    nodes[nowr].second > nodes[nowr + 1].second;
      bool rrup = nowr < nodes.size() - 1 &&
                  nodes[nowr].second < nodes[nowr + 1].second;
      if (nowl && !lldown && !llup) {
        const int nextl = nowl - 1;
        const int nextr = nowr;
        ld nexttime =
            nowtime + gettime(nodes, nowl, nextl) + gettime(nodes, nowr, nextr);
        if (nexttime < dp[nextl][nextr]) {
          dp[nextl][nextr] = nexttime;
          que.push(aa{nextl, nextr, nexttime});
        }
      }
      if (!lrdown && !lrup) {
        const int nextl = nowl + 1;
        const int nextr = nowr;
        ld nexttime =
            nowtime + gettime(nodes, nowl, nextl) + gettime(nodes, nowr, nextr);
        if (nexttime < dp[nextl][nextr]) {
          dp[nextl][nextr] = nexttime;
          que.push(aa{nextl, nextr, nexttime});
        }
      }
      if (nowr < nodes.size() - 1 && !rrdown && !rrup) {
        const int nextl = nowl;
        const int nextr = nowr + 1;
        ld nexttime =
            nowtime + gettime(nodes, nowl, nextl) + gettime(nodes, nowr, nextr);
        if (nexttime < dp[nextl][nextr]) {
          dp[nextl][nextr] = nexttime;
          que.push(aa{nextl, nextr, nexttime});
        }
      }
      if (!rldown && !rlup) {
        const int nextl = nowl;
        const int nextr = nowr - 1;
        ld nexttime =
            nowtime + gettime(nodes, nowl, nextl) + gettime(nodes, nowr, nextr);
        if (nexttime < dp[nextl][nextr]) {
          dp[nextl][nextr] = nexttime;
          que.push(aa{nextl, nextr, nexttime});
        }
      }
      if (lldown) {
        const int nextl = nowl - 1;
        if (rldown) {
          const int nextr = nowr - 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
        if (rrdown) {
          const int nextr = nowr + 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
      }
      if (lrdown) {
        const int nextl = nowl + 1;
        if (rldown) {
          const int nextr = nowr - 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
        if (rrdown) {
          const int nextr = nowr + 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
      }
      if (llup) {
        const int nextl = nowl - 1;
        if (rlup) {
          const int nextr = nowr - 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
        if (rrup) {
          const int nextr = nowr + 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
      }
      if (lrup) {
        const int nextl = nowl + 1;
        if (rlup) {
          const int nextr = nowr - 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
        if (rrup) {
          const int nextr = nowr + 1;
          ld nexttime = nowtime + gettime(nodes, nowl, nextl) +
                        gettime(nodes, nowr, nextr);
          if (nexttime < dp[nextl][nextr]) {
            dp[nextl][nextr] = nexttime;
            que.push(aa{nextl, nextr, nexttime});
          }
        }
      }
    }
    cout << fixed << setprecision(22) << ans << endl;
  }

  return 0;
}