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

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

#include <complex>
typedef complex<double> P;
typedef vector<double> vd;
typedef vector<vd> vvd;

#define EQ(x, y) (abs((x) - (y)) < EPS)
#define LT(x, y) ((x) - (y) <= -EPS)

double cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }

int is_point_on_ls(P a, P b, P c) {
  return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
}

int is_intersected_ls(P a1, P a2, P b1, P b2) {
  if ((cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < -EPS) &&
      (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - a1) < -EPS))
    return true;
  return is_point_on_ls(a1, a2, b1) || is_point_on_ls(a1, a2, b2) ||
         is_point_on_ls(b1, b2, a1) || is_point_on_ls(b1, b2, a2);
}

struct state {
  int p;
  double d;
  state(int p, double d) : p(p), d(d){};
  bool operator<(const state &o) const { return o.d < d; }
};

int main() {
  int NA, NB;
  cin >> NA >> NB;

  vector<P> pA(NA), pB(NB);
  double x, y;
  REP(i, NA) {
    cin >> x >> y;
    pA[i] = P(x, y);
  }
  REP(i, NB) {
    cin >> x >> y;
    pB[i] = P(x, y);
  }

  cout.precision(16);
  if (is_intersected_ls(pA[0], pA[1], pB[0], pB[1])) {
    double ans = INF;

    {
      vvd distA(NA, vd(NA, INF));
      REP(i, NA - 1) {
        FOR(j, i + 1, NA - 1) {
          if (!is_intersected_ls(pA[i], pA[j], pB[0], pB[1])) {
            distA[i][j] = distA[j][i] = abs(pA[i] - pA[j]);
          }
        }
      }
      priority_queue<state> Q;
      Q.push(state(0, 0));
      vd costA(NA, INF);
      costA[0] = 0;
      while (!Q.empty()) {
        state st = Q.top();
        Q.pop();
        if (st.p == 1) {
          ans = min(ans, abs(pB[0] - pB[1]) + st.d);
          break;
        }
        REP(i, NA) {
          if (st.p != i && !EQ(distA[st.p][i], INF)) {
            double nd = st.d + distA[st.p][i];
            if (LT(nd, costA[i])) {
              costA[i] = nd;
              Q.push(state(i, nd));
            }
          }
        }
      }
    }

    {
      vvd distB(NB, vd(NB, INF));
      REP(i, NB - 1) {
        FOR(j, i + 1, NB - 1) {
          if (!is_intersected_ls(pB[i], pB[j], pA[0], pA[1])) {
            distB[i][j] = distB[j][i] = abs(pB[i] - pB[j]);
          }
        }
      }
      priority_queue<state> Q;
      Q.push(state(0, 0));
      vd costB(NB, INF);
      costB[0] = 0;
      while (!Q.empty()) {
        state st = Q.top();
        Q.pop();
        if (st.p == 1) {
          ans = min(ans, abs(pA[0] - pA[1]) + st.d);
          break;
        }
        REP(i, NB) {
          if (st.p != i && !EQ(distB[st.p][i], INF)) {
            double nd = st.d + distB[st.p][i];
            if (LT(nd, costB[i])) {
              costB[i] = nd;
              Q.push(state(i, nd));
            }
          }
        }
      }
    }

    if (EQ(ans, INF)) {
      cout << -1 << endl;
    } else {
      cout << ans << endl;
    }

  } else {
    cout << abs(pA[0] - pA[1]) + abs(pB[0] - pB[1]) << endl;
    ;
  }

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

#include <complex>
typedef complex<double> P;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<vd> vvd;

#define EQ(x, y) (abs((x) - (y)) < EPS)
#define LT(x, y) ((x) - (y) <= -EPS)

double dist(P a, P b) { return abs(a - b); }

double cross(P a, P b) { return (a.real() * b.imag() - a.imag() * b.real()); }

bool is_point_on_ls(P a, P b, P c) {
  return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
}

bool is_intersected_ls(P a1, P a2, P b1, P b2) {
  if ((cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - b1) < -EPS) &&
      (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < -EPS))
    return true;
  return is_point_on_ls(a1, a2, b1) || is_point_on_ls(a1, a2, b2) ||
         is_point_on_ls(b1, b2, a1) || is_point_on_ls(b1, b2, a2);
}

struct state {
  int p;
  double d;
  state(int p, double d) : p(p), d(d){};
  bool operator<(const state &o) const { return o.d < d; }
};

int main() {
  int NA, NB;
  cin >> NA >> NB;

  vp pa(NA), pb(NB);
  double x, y;
  REP(i, NA) {
    cin >> x >> y;
    pa[i] = P(x, y);
  }
  REP(i, NB) {
    cin >> x >> y;
    pb[i] = P(x, y);
  }

  double ans = INF;
  if (!is_intersected_ls(pa[0], pa[1], pb[0], pb[1])) {
    ans = min(ans, dist(pa[0], pa[1]) + dist(pb[0], pb[1]));
  } else {
    vvi tableA(NA, vi(0));
    double distb = dist(pb[0], pb[1]);
    REP(i, NA) {
      REP(j, NA) {
        if (i != j && !is_intersected_ls(pb[0], pb[1], pa[i], pa[j])) {
          tableA[i].push_back(j);
        }
      }
    }
    vd costA(NA, INF);
    costA[0] = 0;
    priority_queue<state> Q;
    Q.push(state(0, 0));
    while (!Q.empty()) {
      state st = Q.top();
      Q.pop();
      if (st.p == 1) {
        ans = min(ans, st.d + distb);
      }
      REP(i, tableA[st.p].size()) {
        int np = tableA[st.p][i];
        double nd = st.d + dist(pa[st.p], pa[np]);
        if (LT(nd, costA[np])) {
          costA[np] = nd;
          Q.push(state(np, nd));
        }
      }
    }

    vvi tableB(NB, vi(0));
    double dista = dist(pa[0], pa[1]);
    REP(i, NB) {
      REP(j, NB) {
        if (i != j && !is_intersected_ls(pa[0], pa[1], pb[i], pb[j])) {
          tableB[i].push_back(j);
        }
      }
    }
    vd costB(NB, INF);
    costB[0] = 0;
    while (!Q.empty()) {
      state st = Q.top();
      Q.pop();
      if (st.p == 1) {
        ans = min(ans, st.d + dista);
      }
      REP(i, tableB[st.p].size()) {
        int np = tableB[st.p][i];
        double nd = st.d + dist(pb[st.p], pb[np]);
        if (LT(nd, costB[np])) {
          costB[np] = nd;
          Q.push(state(np, nd));
        }
      }
    }
  }

  if (EQ(ans, INF)) {
    cout << -1 << endl;
  } else {
    printf("%.10f\\n", ans);
  }

  return 0;
}