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

#include <algorithm>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <vector>
using namespace std;
const double EPS = 1e-7;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a) { return max(a, -a); }
struct Pt {
  double x, y;
  Pt() {}
  Pt(double x, double y) : x(x), y(y) {}
  Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
  Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
  Pt operator*(const Pt &a) const {
    return Pt(x * a.x - y * a.y, x * a.y + y * a.x);
  }
  Pt operator-() const { return Pt(-x, -y); }
  Pt operator*(const double &k) const { return Pt(x * k, y * k); }
  Pt operator/(const double &k) const { return Pt(x / k, y / k); }
  bool operator==(const Pt &a) const { return !sig(x - a.x) && !sig(y - a.y); }
  double ABS() const { return sqrt(x * x + y * y); }
  double abs2() const { return x * x + y * y; }
  double arg() const { return atan2(y, x); }
  double dot(const Pt &a) const { return x * a.x + y * a.y; }
  double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }

int iSP(Pt a, Pt b, Pt c) {
  int s = sig((b - a).det(c - a));
  if (s)
    return s;
  if (sig((b - a).dot(c - a)) < 0)
    return -2; // c-a-b
  if (sig((a - b).dot(c - b)) < 0)
    return +2; // a-b-c
  return 0;
}
int iLL(Pt a, Pt b, Pt c, Pt d) {
  if (sig((b - a).det(d - c)))
    return 1; // intersect
  if (sig((b - a).det(c - a)))
    return 0; // parallel
  return -1;  // correspond
}
bool iLS(Pt a, Pt b, Pt c, Pt d) {
  return (sig(tri(a, b, c)) * sig(tri(a, b, d)) <= 0);
}
bool iSS(Pt a, Pt b, Pt c, Pt d) {
  return (iSP(a, b, c) * iSP(a, b, d) <= 0 && iSP(c, d, a) * iSP(c, d, b) <= 0);
}
bool iSSstrict(Pt a, Pt b, Pt c, Pt d) {
  return (sig(tri(a, b, c)) * sig(tri(a, b, d)) < 0 &&
          sig(tri(c, d, a)) * sig(tri(c, d, b)) < 0);
}
Pt pLL(Pt a, Pt b, Pt c, Pt d) {
  b = b - a;
  d = d - c;
  return a + b * (c - a).det(d) / b.det(d);
}
Pt hLP(Pt a, Pt b, Pt c) { return pLL(a, b, c, c + (b - a) * Pt(0, 1)); }
double dLP(Pt a, Pt b, Pt c) { return ABS(tri(a, b, c)) / (b - a).ABS(); }
double dSP(Pt a, Pt b, Pt c) {
  if (sig((b - a).dot(c - a)) <= 0)
    return (c - a).ABS();
  if (sig((a - b).dot(c - b)) <= 0)
    return (c - b).ABS();
  return ABS(tri(a, b, c)) / (b - a).ABS();
}
double dLL(Pt a, Pt b, Pt c, Pt d) {
  return iLL(a, b, c, d) ? 0 : dLP(a, b, c);
}
double dLS(Pt a, Pt b, Pt c, Pt d) {
  return iLS(a, b, c, d) ? 0 : min(dLP(a, b, c), dLP(a, b, d));
}
double dSS(Pt a, Pt b, Pt c, Pt d) {
  return iSS(a, b, c, d) ? 0
                         : min(min(dSP(a, b, c), dSP(a, b, d)),
                               min(dSP(c, d, a), dSP(c, d, b)));
}
int convexCut(int n, Pt p[], Pt a, Pt b, Pt q[]) {
  int m = 0, i;
  p[n] = p[0];
  for (i = 0; i < n; ++i) {
    if (sig(tri(a, b, p[i])) >= 0)
      q[m++] = p[i];
    if (sig(tri(a, b, p[i])) * sig(tri(a, b, p[i + 1])) < 0)
      q[m++] = pLL(a, b, p[i], p[i + 1]);
  }
  q[m] = q[0];
  return m;
}
int iCC(Pt a, double r, Pt b, double s) {
  double d = (b - a).ABS();
  if (sig(d) == 0 && sig(r - s) == 0)
    return -1; // correspond
  if (sig(r - s - d) > 0)
    return +2; // r > s
  if (sig(s - r - d) > 0)
    return -2; // s > r
  return (sig(r + s - d) >= 0) ? 1 : 0;
}
bool iCS(Pt a, double r, Pt b, Pt c) {
  return (sig(r - dSP(b, c, a)) >= 0 &&
          sig(r - max((b - a).ABS(), (c - a).ABS())) <= 0);
}
pair<Pt, Pt> pCC(Pt a, double r, Pt b, double s) {
  double d = (b - a).ABS();
  double x = (d * d + r * r - s * s) / (d * 2);
  Pt e = (b - a) / d, w = e * Pt(0, 1) * sqrt(max(r * r - x * x, 0.0));
  return make_pair(a + e * x - w, a + e * x + w);
}
pair<Pt, Pt> pCL(Pt a, double r, Pt b, Pt c) {
  Pt h = b + (c - b) * (c - b).dot(a - b) / (c - b).abs2(); // perp(b, c, a)
  double d = (h - a).ABS();
  double y = sqrt(max(r * r - d * d, 0.0));
  Pt e = (c - b) / (c - b).ABS();
  return make_pair(h - e * y, h + e * y);
}
pair<Pt, Pt> tCP(Pt a, double r, Pt b) {
  double d2 = (b - a).abs2();
  double x = sqrt(max(d2 - r * r, 0.0));
  Pt h = a + (b - a) * (r * r / d2);
  Pt w = (b - a) * Pt(0, 1) * (x * r / d2);
  return make_pair(h - w, h + w);
}
double aCC(Pt a, double r, Pt b, double s) {
  double d = (a - b).ABS();
  if (sig(r - s - d) >= 0)
    return s * s * PI;
  if (sig(s - r - d) >= 0)
    return r * r * PI;
  if (sig(r + s - d) <= 0)
    return 0;
  double x = (d * d + r * r - s * s) / (d * 2);
  double h = sqrt(r * r - x * x);
  return r * r * atan2(h, x) + s * s * atan2(h, d - x) - d * h;
}
// inside: +1 on: 0 outside: -1
int sGP(int n, Pt p[], Pt a) {
  int side = -1, i;
  p[n] = p[0];
  for (i = 0; i < n; ++i) {
    Pt p0 = p[i] - a, p1 = p[i + 1] - a;
    if (sig(p0.det(p1)) == 0 && sig(p0.dot(p1)) <= 0)
      return 0;
    if (p0.y > p1.y)
      swap(p0, p1);
    if (sig(p0.y) <= 0 && 0 < sig(p1.y) && sig(p0.det(p1)) > 0)
      side = -side;
  }
  return side;
}
int sAP(Pt a, Pt b, Pt c) {
  return sig(a.det(c)) - sig(b.det(c)) - sig(a.det(b));
}

int s_a[1100], s_b[1100], s_ab[1100];
bool iGSstrict(vector<Pt> p, Pt a, Pt b) {
  int i;
  int n = p.size();
  p.push_back(p[0]);
  p.push_back(p[1]);
  //	if (sGP(n, p, a) > 0 || sGP(n, p, b) > 0) return 1;
  for (i = 0; i <= n; ++i) {
    s_a[i] = sig(tri(p[i], p[i + 1], a));
    s_b[i] = sig(tri(p[i], p[i + 1], b));
    s_ab[i] = sig(tri(a, b, p[i]));
  }
  for (i = 0; i < n; ++i) {
    if (s_a[i] * s_b[i] < 0 && s_ab[i] * s_ab[i + 1] < 0)
      return 1;
  }
  for (i = 0; i < n; ++i) {
    if (s_a[i] == 0 && s_b[i] > 0 && sig((a - p[i]).dot(a - p[i + 1])) < 0)
      return 1;
    if (s_b[i] == 0 && s_a[i] > 0 && sig((b - p[i]).dot(b - p[i + 1])) < 0)
      return 1;
  }
  for (i = 0; i < n; ++i)
    if (s_ab[i + 1] == 0 && sig((p[i + 1] - a).dot(p[i + 1] - b)) <= 0) {
      if (!(p[i + 1] == a) &&
          sAP(p[i + 2] - p[i + 1], p[i] - p[i + 1], a - p[i + 1]) > 0)
        return 1;
      if (!(p[i + 1] == b) &&
          sAP(p[i + 2] - p[i + 1], p[i] - p[i + 1], b - p[i + 1]) > 0)
        return 1;
    }
  return 0;
}
vector<Pt> p[110];
vector<Pt> q;
vector<pair<Pt, Pt>> edge;
double ijk[110000];
int v[110000];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    double bx, by;
    scanf("%lf%lf", &bx, &by);
    Pt bm = Pt(bx, by);
    for (int i = 0; i < a; i++)
      p[i].clear();
    for (int i = 0; i < a; i++) {
      int c;
      scanf("%d", &c);
      for (int j = 0; j < c; j++) {
        double ix, iy;
        scanf("%lf%lf", &ix, &iy);
        p[i].push_back(Pt(ix, iy));
      }
    }
    bool zr = false;
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < p[i].size(); j++) {
        if (iSSstrict(p[i][j], p[i][(j + 1) % p[i].size()], Pt(0, 0), bm))
          zr = true;
      }
    }
    if (zr) {
      printf("%.12f\\n", 0.0);
      continue;
    }
    q.clear();
    edge.clear();
    q.push_back(Pt(0, 0));
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < p[i].size(); j++) {
        Pt r = bm + (p[i][j] - bm) * 1000000;
        bool tc = false;
        for (int k = 0; k < a; k++)
          for (int l = 0; l < p[k].size(); l++) {
            if (iSSstrict(p[k][l], p[k][(l + 1) % p[k].size()], p[i][j], r)) {
              r = pLL(p[k][l], p[k][(l + 1) % p[k].size()], p[i][j], r);
            }
            if (iSSstrict(p[k][l], p[k][(l + 1) % p[k].size()], bm, p[i][j])) {
              tc = true;
              break;
            }
          }
        if (tc)
          continue;
        q.push_back(p[i][j]);
        if (r.ABS() < 100000)
          q.push_back(r);
        if (!iGSstrict(p[i], p[i][j], r))
          edge.push_back(make_pair(p[i][j], r));
      }
    }

    int n = q.size();
    for (int i = 0; i < n; i++)
      ijk[i] = 999999999;
    for (int i = 0; i < n; i++)
      v[i] = 0;
    ijk[0] = 0;
    for (int i = 0; i < n; i++) {
      double best = 99999999;
      int at = -1;
      for (int j = 0; j < n; j++) {
        if (!v[j] && best > ijk[j]) {
          best = ijk[j];
          at = j;
        }
      }
      if (!~at)
        break;
      v[at] = 1;
      for (int j = 0; j < n; j++) {
        if (v[j] || ijk[at] + (q[at] - q[j]).ABS() + EPS > ijk[j])
          continue;
        bool ok = true;
        for (int k = 0; k < a; k++) {
          if (iGSstrict(p[k], q[at], q[j])) {
            ok = false;
            break;
          }
        }
        if (ok) {
          ijk[j] = min(ijk[j], ijk[at] + (q[at] - q[j]).ABS());
        }
      }
    }
    double ret = 999999999;
    // for(int i=0;i<edge.size();i++)printf("(%f %f), (%f
    // %f)\\n",edge[i].first.x,edge[i].first.y,edge[i].second.x,edge[i].second.y);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < edge.size(); j++) {
        Pt L = edge[j].first;
        Pt R = edge[j].second;
        Pt H = hLP(edge[j].first, edge[j].second, q[i]);
        bool ok;
        ok = true;
        if (ret < EPS + ijk[i] + (q[i] - L).ABS())
          ok = false;
        for (int k = 0; ok && k < a; k++)
          if (iGSstrict(p[k], q[i], L)) {
            ok = false;
            break;
          }
        if (ok)
          ret = min(ret, ijk[i] + (q[i] - L).ABS());
        ok = true;
        if (ret < EPS + ijk[i] + (q[i] - R).ABS())
          ok = false;
        for (int k = 0; ok && k < a; k++)
          if (iGSstrict(p[k], q[i], R)) {
            ok = false;
            break;
          }
        if (ok)
          ret = min(ret, ijk[i] + (q[i] - R).ABS());
        ok = true;
        if (ret < EPS + ijk[i] + (q[i] - H).ABS())
          ok = false;
        for (int k = 0; ok && k < a; k++)
          if (iGSstrict(p[k], q[i], H)) {
            ok = false;
            break;
          }
        if (ok && iSP(L, H, R) == 2) {
          ret = min(ret, ijk[i] + (q[i] - H).ABS());
        }
      }
    }
    printf("%.12f\\n", ret);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <vector>
using namespace std;
const double EPS = 1e-7;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a) { return max(a, -a); }
struct Pt {
  double x, y;
  Pt() {}
  Pt(double x, double y) : x(x), y(y) {}
  Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
  Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
  Pt operator*(const Pt &a) const {
    return Pt(x * a.x - y * a.y, x * a.y + y * a.x);
  }
  Pt operator-() const { return Pt(-x, -y); }
  Pt operator*(const double &k) const { return Pt(x * k, y * k); }
  Pt operator/(const double &k) const { return Pt(x / k, y / k); }
  bool operator==(const Pt &a) const { return !sig(x - a.x) && !sig(y - a.y); }
  double ABS() const { return sqrt(x * x + y * y); }
  double abs2() const { return x * x + y * y; }
  double arg() const { return atan2(y, x); }
  double dot(const Pt &a) const { return x * a.x + y * a.y; }
  double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }

int iSP(Pt a, Pt b, Pt c) {
  int s = sig((b - a).det(c - a));
  if (s)
    return s;
  if (sig((b - a).dot(c - a)) < 0)
    return -2; // c-a-b
  if (sig((a - b).dot(c - b)) < 0)
    return +2; // a-b-c
  return 0;
}
int iLL(Pt a, Pt b, Pt c, Pt d) {
  if (sig((b - a).det(d - c)))
    return 1; // intersect
  if (sig((b - a).det(c - a)))
    return 0; // parallel
  return -1;  // correspond
}
bool iLS(Pt a, Pt b, Pt c, Pt d) {
  return (sig(tri(a, b, c)) * sig(tri(a, b, d)) <= 0);
}
bool iSS(Pt a, Pt b, Pt c, Pt d) {
  return (iSP(a, b, c) * iSP(a, b, d) <= 0 && iSP(c, d, a) * iSP(c, d, b) <= 0);
}
bool iSSstrict(Pt a, Pt b, Pt c, Pt d) {
  return (sig(tri(a, b, c)) * sig(tri(a, b, d)) < 0 &&
          sig(tri(c, d, a)) * sig(tri(c, d, b)) < 0);
}
Pt pLL(Pt a, Pt b, Pt c, Pt d) {
  b = b - a;
  d = d - c;
  return a + b * (c - a).det(d) / b.det(d);
}
Pt hLP(Pt a, Pt b, Pt c) { return pLL(a, b, c, c + (b - a) * Pt(0, 1)); }
double dLP(Pt a, Pt b, Pt c) { return ABS(tri(a, b, c)) / (b - a).ABS(); }
double dSP(Pt a, Pt b, Pt c) {
  if (sig((b - a).dot(c - a)) <= 0)
    return (c - a).ABS();
  if (sig((a - b).dot(c - b)) <= 0)
    return (c - b).ABS();
  return ABS(tri(a, b, c)) / (b - a).ABS();
}
double dLL(Pt a, Pt b, Pt c, Pt d) {
  return iLL(a, b, c, d) ? 0 : dLP(a, b, c);
}
double dLS(Pt a, Pt b, Pt c, Pt d) {
  return iLS(a, b, c, d) ? 0 : min(dLP(a, b, c), dLP(a, b, d));
}
double dSS(Pt a, Pt b, Pt c, Pt d) {
  return iSS(a, b, c, d) ? 0
                         : min(min(dSP(a, b, c), dSP(a, b, d)),
                               min(dSP(c, d, a), dSP(c, d, b)));
}
int convexCut(int n, Pt p[], Pt a, Pt b, Pt q[]) {
  int m = 0, i;
  p[n] = p[0];
  for (i = 0; i < n; ++i) {
    if (sig(tri(a, b, p[i])) >= 0)
      q[m++] = p[i];
    if (sig(tri(a, b, p[i])) * sig(tri(a, b, p[i + 1])) < 0)
      q[m++] = pLL(a, b, p[i], p[i + 1]);
  }
  q[m] = q[0];
  return m;
}
int iCC(Pt a, double r, Pt b, double s) {
  double d = (b - a).ABS();
  if (sig(d) == 0 && sig(r - s) == 0)
    return -1; // correspond
  if (sig(r - s - d) > 0)
    return +2; // r > s
  if (sig(s - r - d) > 0)
    return -2; // s > r
  return (sig(r + s - d) >= 0) ? 1 : 0;
}
bool iCS(Pt a, double r, Pt b, Pt c) {
  return (sig(r - dSP(b, c, a)) >= 0 &&
          sig(r - max((b - a).ABS(), (c - a).ABS())) <= 0);
}
pair<Pt, Pt> pCC(Pt a, double r, Pt b, double s) {
  double d = (b - a).ABS();
  double x = (d * d + r * r - s * s) / (d * 2);
  Pt e = (b - a) / d, w = e * Pt(0, 1) * sqrt(max(r * r - x * x, 0.0));
  return make_pair(a + e * x - w, a + e * x + w);
}
pair<Pt, Pt> pCL(Pt a, double r, Pt b, Pt c) {
  Pt h = b + (c - b) * (c - b).dot(a - b) / (c - b).abs2(); // perp(b, c, a)
  double d = (h - a).ABS();
  double y = sqrt(max(r * r - d * d, 0.0));
  Pt e = (c - b) / (c - b).ABS();
  return make_pair(h - e * y, h + e * y);
}
pair<Pt, Pt> tCP(Pt a, double r, Pt b) {
  double d2 = (b - a).abs2();
  double x = sqrt(max(d2 - r * r, 0.0));
  Pt h = a + (b - a) * (r * r / d2);
  Pt w = (b - a) * Pt(0, 1) * (x * r / d2);
  return make_pair(h - w, h + w);
}
double aCC(Pt a, double r, Pt b, double s) {
  double d = (a - b).ABS();
  if (sig(r - s - d) >= 0)
    return s * s * PI;
  if (sig(s - r - d) >= 0)
    return r * r * PI;
  if (sig(r + s - d) <= 0)
    return 0;
  double x = (d * d + r * r - s * s) / (d * 2);
  double h = sqrt(r * r - x * x);
  return r * r * atan2(h, x) + s * s * atan2(h, d - x) - d * h;
}
// inside: +1 on: 0 outside: -1
int sGP(int n, Pt p[], Pt a) {
  int side = -1, i;
  p[n] = p[0];
  for (i = 0; i < n; ++i) {
    Pt p0 = p[i] - a, p1 = p[i + 1] - a;
    if (sig(p0.det(p1)) == 0 && sig(p0.dot(p1)) <= 0)
      return 0;
    if (p0.y > p1.y)
      swap(p0, p1);
    if (sig(p0.y) <= 0 && 0 < sig(p1.y) && sig(p0.det(p1)) > 0)
      side = -side;
  }
  return side;
}
int sAP(Pt a, Pt b, Pt c) {
  return sig(a.det(c)) - sig(b.det(c)) - sig(a.det(b));
}

int s_a[1100], s_b[1100], s_ab[1100];
bool iGSstrict(vector<Pt> p, Pt a, Pt b) {
  int i;
  int n = p.size();
  p.push_back(p[0]);
  p.push_back(p[1]);
  //	if (sGP(n, p, a) > 0 || sGP(n, p, b) > 0) return 1;
  for (i = 0; i <= n; ++i) {
    s_a[i] = sig(tri(p[i], p[i + 1], a));
    s_b[i] = sig(tri(p[i], p[i + 1], b));
    s_ab[i] = sig(tri(a, b, p[i]));
  }
  for (i = 0; i < n; ++i) {
    if (s_a[i] * s_b[i] < 0 && s_ab[i] * s_ab[i + 1] < 0)
      return 1;
  }
  for (i = 0; i < n; ++i) {
    if (s_a[i] == 0 && s_b[i] > 0 && sig((a - p[i]).dot(a - p[i + 1])) < 0)
      return 1;
    if (s_b[i] == 0 && s_a[i] > 0 && sig((b - p[i]).dot(b - p[i + 1])) < 0)
      return 1;
  }
  for (i = 0; i < n; ++i)
    if (s_ab[i + 1] == 0 && sig((p[i + 1] - a).dot(p[i + 1] - b)) <= 0) {
      if (!(p[i + 1] == a) &&
          sAP(p[i + 2] - p[i + 1], p[i] - p[i + 1], a - p[i + 1]) > 0)
        return 1;
      if (!(p[i + 1] == b) &&
          sAP(p[i + 2] - p[i + 1], p[i] - p[i + 1], b - p[i + 1]) > 0)
        return 1;
    }
  return 0;
}
vector<Pt> p[110];
vector<Pt> q;
vector<pair<Pt, Pt>> edge;
double ijk[110000];
int v[110000];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    double bx, by;
    scanf("%lf%lf", &bx, &by);
    Pt bm = Pt(bx, by);
    for (int i = 0; i < a; i++)
      p[i].clear();
    for (int i = 0; i < a; i++) {
      int c;
      scanf("%d", &c);
      for (int j = 0; j < c; j++) {
        double ix, iy;
        scanf("%lf%lf", &ix, &iy);
        p[i].push_back(Pt(ix, iy));
      }
    }
    bool zr = false;
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < p[i].size(); j++) {
        if (iSSstrict(p[i][j], p[i][(j + 1) % p[i].size()], Pt(0, 0), bm))
          zr = true;
      }
    }
    if (zr) {
      printf("%.12f\\n", 0.0);
      continue;
    }
    q.clear();
    edge.clear();
    q.push_back(Pt(0, 0));
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < p[i].size(); j++) {
        Pt r = bm + (p[i][j] - bm) * 1000000;
        bool tc = false;
        for (int k = 0; k < a; k++)
          for (int l = 0; l < p[k].size(); l++) {
            if (iSSstrict(p[k][l], p[k][(l + 1) % p[k].size()], p[i][j], r)) {
              r = pLL(p[k][l], p[k][(l + 1) % p[k].size()], p[i][j], r);
            }
            if (iSSstrict(p[k][l], p[k][(l + 1) % p[k].size()], bm, p[i][j])) {
              tc = true;
              break;
            }
          }
        if (tc)
          continue;
        q.push_back(p[i][j]);
        if (r.ABS() < 100000)
          q.push_back(r);
        if (!iGSstrict(p[i], p[i][j], r))
          edge.push_back(make_pair(p[i][j], r));
      }
    }

    int n = q.size();
    for (int i = 0; i < n; i++)
      ijk[i] = 999999999;
    for (int i = 0; i < n; i++)
      v[i] = 0;
    ijk[0] = 0;
    for (int i = 0; i < n; i++) {
      double best = 99999999;
      int at = -1;
      for (int j = 0; j < n; j++) {
        if (!v[j] && best > ijk[j]) {
          best = ijk[j];
          at = j;
        }
      }
      if (!~at)
        break;
      v[at] = 1;
      for (int j = 0; j < n; j++) {
        if (v[j] || ijk[at] + (q[at] - q[j]).ABS() + EPS > ijk[j])
          continue;
        bool ok = true;
        for (int k = 0; k < a; k++) {
          if (iGSstrict(p[k], q[at], q[j])) {
            ok = false;
            break;
          }
        }
        if (ok) {
          ijk[j] = min(ijk[j], ijk[at] + (q[at] - q[j]).ABS());
        }
      }
    }
    double ret = 999999999;
    // for(int i=0;i<edge.size();i++)printf("(%f %f), (%f
    // %f)\\n",edge[i].first.x,edge[i].first.y,edge[i].second.x,edge[i].second.y);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < edge.size(); j++) {
        Pt L = edge[j].first;
        Pt R = edge[j].second;
        Pt H = hLP(edge[j].first, edge[j].second, q[i]);
        bool ok;
        ok = true;
        for (int k = 0; k < a; k++)
          if (iGSstrict(p[k], q[i], L)) {
            ok = false;
            break;
          }
        if (ok)
          ret = min(ret, ijk[i] + (q[i] - L).ABS());
        ok = true;
        for (int k = 0; k < a; k++)
          if (iGSstrict(p[k], q[i], R)) {
            ok = false;
            break;
          }
        if (ok)
          ret = min(ret, ijk[i] + (q[i] - R).ABS());
        ok = true;
        for (int k = 0; k < a; k++)
          if (iGSstrict(p[k], q[i], H)) {
            ok = false;
            break;
          }
        if (ok && iSP(L, H, R) == 2) {
          ret = min(ret, ijk[i] + (q[i] - H).ABS());
        }
      }
    }
    printf("%.12f\\n", ret);
  }
}