Problem p01927 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second

struct Line {
public:
  Point a, b;
};

ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
bool isis_sp(Line s, Point p) {
  return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
bool isis_ss(Line s, Line t) {
  if (isis_sp(s, t.a) || isis_sp(s, t.b) || isis_sp(t, s.a) || isis_sp(t, s.b))
    return true;
  return (cross(s.b - s.a, t.a - s.a) * cross(s.b - s.a, t.b - s.a) < -eps &&
          cross(t.b - t.a, s.a - t.a) * cross(t.b - t.a, s.b - t.a) < -eps);
}

Point proj(Line l, Point p) {
  ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + t * (l.a - l.b);
}
ld dist_sp(Line s, Point p) {
  Point r = proj(s, p);
  return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
ld dist_ss(Line s, Line t) {
  if (isis_ss(s, t))
    return 0;
  return min(
      {dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b)});
}
int n;
ld h[100];
vector<Point> vp[100];
vector<Point> rvp[100];
vector<Line> vl[100];

struct edge {
  int to;
  ld cost;
};
vector<edge> G[102];
ld dist[102];

typedef pair<ld, int> speP;
priority_queue<speP, vector<speP>, greater<speP>> q;
void solve() {
  cout << fixed << setprecision(5);
  while (cin >> n, n) {
    rep(i, n + 2) G[i].clear();
    rep(i, n) {
      vl[i].clear();
      vp[i].clear();
      rvp[i].clear();
      int l;
      cin >> l >> h[i];
      vp[i].resize(l);
      rep(j, l) {
        ld x, y;
        cin >> x >> y;
        vp[i][j] = {x, y};
      }
    }
    ld theta, phi;
    cin >> theta >> phi;
    theta = theta * pi / 180.0;
    phi = phi * pi / 180.0;
    theta += pi;
    rep(i, n) {

      rvp[i].resize(vp[i].size());
      ld rh = h[i] / tan(phi);
      rep(j, vp[i].size()) {
        ld dx = cos(theta) * rh, dy = sin(theta) * rh;
        rvp[i][j] = {dx + real(vp[i][j]), dy + imag(vp[i][j])};
        vl[i].push_back({vp[i][j], rvp[i][j]});
      }
      rep(j, vp[i].size() - 1) { vl[i].push_back({vp[i][j], vp[i][j + 1]}); }
      vl[i].push_back({vp[i][0], vp[i][vp[i].size() - 1]});
      rep(j, vp[i].size() - 1) { vl[i].push_back({rvp[i][j], rvp[i][j + 1]}); }
      vl[i].push_back({rvp[i][0], rvp[i][rvp[i].size() - 1]});
    }
    rep(i, n) {
      Rep(j, i + 1, n) {
        ld d = INF;
        rep(k, vp[i].size()) {
          Rep(l, vp[j].size(), vl[j].size()) {
            if (isis_ss(vl[i][k], vl[j][l])) {
              d = 0;
              break;
            }
          }
          if (d == 0)
            break;
          rep(l, vp[j].size()) {
            d = min(d, dist_sp(vl[i][k], vp[j][l]));
            d = min(d, dist_sp(vl[i][k], rvp[j][l]));
          }
        }
        if (d > 0) {
          rep(l, vp[j].size()) {
            Rep(k, vp[i].size(), vl[i].size()) {
              if (isis_ss(vl[i][k], vl[j][l])) {
                d = 0;
                break;
              }
            }
            if (d == 0)
              break;
            rep(k, vp[i].size()) {
              d = min(d, dist_sp(vl[j][l], vp[i][k]));
              d = min(d, dist_sp(vl[j][l], rvp[i][k]));
            }
          }
        }
        if (d > 0) {
          Rep(k, vp[i].size(), vl[i].size()) {
            Rep(l, vp[j].size(), vl[j].size()) {
              if (k >= 2 * vp[i].size() && l >= 2 * vp[j].size())
                continue;

              d = min(d, dist_ss(vl[i][k], vl[j][l]));
            }
          }
        }
        /*rep(k, vl[i].size()) {
                rep(l, vl[j].size()) {
                        if (k < vp[i].size() && l < vp[j].size())continue;
                        if (k >= 2 * vp[i].size() && l >= 2 *
        vp[j].size())continue; d = min(d, dist_ss(vl[i][k], vl[j][l]));
                }
        }*/
        G[i].push_back({j, d});
        G[j].push_back({i, d});
      }
    }
    Point s, g;
    ld x, y;
    cin >> x >> y;
    s = {x, y};
    cin >> x >> y;
    g = {x, y};
    theta -= pi;
    Point ps, pg;
    rep(i, n) {
      ld rh = h[i] / tan(phi);
      ps = {real(s) + rh * cos(theta), imag(s) + rh * sin(theta)};
      pg = {real(g) + rh * cos(theta), imag(g) + rh * sin(theta)};
      Line ls = {s, ps};
      Line lg = {g, pg};
      bool fs = false, fg = false;
      rep(j, vp[i].size()) {
        Line vpl = {vp[i][j], vp[i][(j + 1) % vp[i].size()]};
        if (isis_ss(ls, vpl)) {
          fs = true;
        }
        if (isis_ss(lg, vpl)) {
          fg = true;
        }
      }
      if (fs) {
        G[n].push_back({i, 0});
        G[i].push_back({n, 0});
      } else {
        ld d = INF;
        rep(j, vl[i].size()) { d = min(d, dist_sp(vl[i][j], s)); }
        G[n].push_back({i, d});
        G[i].push_back({n, d});
      }
      if (fg) {
        G[n + 1].push_back({i, 0});
        G[i].push_back({n + 1, 0});
      } else {
        ld d = INF;
        rep(j, vl[i].size()) { d = min(d, dist_sp(vl[i][j], g)); }
        G[n + 1].push_back({i, d});
        G[i].push_back({n + 1, d});
      }
    }
    G[n].push_back({n + 1, abs(g - s)});
    G[n + 1].push_back({n, abs(g - s)});
    fill(dist, dist + n + 2, INF);
    dist[n] = 0;
    q.push({0, n});
    while (!q.empty()) {
      speP p = q.top();
      q.pop();
      int id = p.second;
      if (p.first > dist[id])
        continue;
      rep(j, G[id].size()) {
        int to = G[id][j].to;
        ld nd = G[id][j].cost + p.first;
        if (nd < dist[to]) {
          dist[to] = nd;
          q.push({nd, to});
        }
      }
    }
    cout << dist[n + 1] << endl;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  // stop
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second

struct Line {
public:
  Point a, b;
};

ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
bool isis_sp(Line s, Point p) {
  return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
bool isis_ss(Line s, Line t) {

  // if (isis_sp(s, t.a) || isis_sp(s, t.b) || isis_sp(t, s.a) || isis_sp(t,
  // s.b))return true;
  return (cross(s.b - s.a, t.a - s.a) * cross(s.b - s.a, t.b - s.a) < -eps &&
          cross(t.b - t.a, s.a - t.a) * cross(t.b - t.a, s.b - t.a) < -eps);
}

Point proj(Line l, Point p) {
  ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + t * (l.a - l.b);
}
ld dist_sp(Line s, Point p) {
  Point r = proj(s, p);
  return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
ld dist_ss(Line s, Line t) {
  if (isis_ss(s, t))
    return 0;
  return min(
      {dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b)});
}
int n;
ld h[100];
vector<Point> vp[100];
vector<Point> rvp[100];
vector<Line> vl[100];

struct edge {
  int to;
  ld cost;
};
vector<edge> G[102];
ld dist[102];

typedef pair<ld, int> speP;
priority_queue<speP, vector<speP>, greater<speP>> q;
void solve() {
  cout << fixed << setprecision(5);
  while (cin >> n, n) {
    rep(i, n + 2) G[i].clear();
    rep(i, n) {
      vl[i].clear();
      vp[i].clear();
      rvp[i].clear();
      int l;
      cin >> l >> h[i];
      vp[i].resize(l);
      rep(j, l) {
        ld x, y;
        cin >> x >> y;
        vp[i][j] = {x, y};
      }
    }
    ld theta, phi;
    cin >> theta >> phi;
    theta = theta * pi / 180.0;
    phi = phi * pi / 180.0;
    theta += pi;
    rep(i, n) {

      rvp[i].resize(vp[i].size());
      ld rh = h[i] / tan(phi);
      rep(j, vp[i].size()) {
        ld dx = cos(theta) * rh, dy = sin(theta) * rh;
        rvp[i][j] = {dx + real(vp[i][j]), dy + imag(vp[i][j])};
        vl[i].push_back({vp[i][j], rvp[i][j]});
      }
      rep(j, vp[i].size() - 1) { vl[i].push_back({vp[i][j], vp[i][j + 1]}); }
      vl[i].push_back({vp[i][0], vp[i][vp[i].size() - 1]});
      rep(j, vp[i].size() - 1) { vl[i].push_back({rvp[i][j], rvp[i][j + 1]}); }
      vl[i].push_back({rvp[i][0], rvp[i][rvp[i].size() - 1]});
    }
    rep(i, n) {
      Rep(j, i + 1, n) {
        ld d = INF;
        rep(k, vp[i].size()) {
          Rep(l, vp[j].size(), vl[j].size()) {
            if (isis_ss(vl[i][k], vl[j][l])) {
              d = 0;
              break;
            }
          }
          if (d == 0)
            break;
          rep(l, vp[j].size()) {
            d = min(d, dist_sp(vl[i][k], vp[j][l]));
            d = min(d, dist_sp(vl[i][k], rvp[j][l]));
          }
        }
        if (d > 0) {
          rep(l, vp[j].size()) {
            Rep(k, vp[i].size(), vl[i].size()) {
              if (isis_ss(vl[i][k], vl[j][l])) {
                d = 0;
                break;
              }
            }
            if (d == 0)
              break;
            rep(k, vp[i].size()) {
              d = min(d, dist_sp(vl[j][l], vp[i][k]));
              d = min(d, dist_sp(vl[j][l], rvp[i][k]));
            }
          }
        }
        if (d > 0) {
          Rep(k, vp[i].size(), vl[i].size()) {
            Rep(l, vp[j].size(), vl[j].size()) {
              if (k >= 2 * vp[i].size() && l >= 2 * vp[j].size())
                continue;

              d = min(d, dist_ss(vl[i][k], vl[j][l]));
            }
          }
        }
        /*rep(k, vl[i].size()) {
                rep(l, vl[j].size()) {
                        if (k < vp[i].size() && l < vp[j].size())continue;
                        if (k >= 2 * vp[i].size() && l >= 2 *
        vp[j].size())continue; d = min(d, dist_ss(vl[i][k], vl[j][l]));
                }
        }*/
        G[i].push_back({j, d});
        G[j].push_back({i, d});
      }
    }
    Point s, g;
    ld x, y;
    cin >> x >> y;
    s = {x, y};
    cin >> x >> y;
    g = {x, y};
    theta -= pi;
    Point ps, pg;
    rep(i, n) {
      ld rh = h[i] / tan(phi);
      ps = {real(s) + rh * cos(theta), imag(s) + rh * sin(theta)};
      pg = {real(g) + rh * cos(theta), imag(g) + rh * sin(theta)};
      Line ls = {s, ps};
      Line lg = {g, pg};
      bool fs = false, fg = false;
      rep(j, vp[i].size()) {
        Line vpl = {vp[i][j], vp[i][(j + 1) % vp[i].size()]};
        if (isis_ss(ls, vpl)) {
          fs = true;
        }
        if (isis_ss(lg, vpl)) {
          fg = true;
        }
      }
      if (fs) {
        G[n].push_back({i, 0});
        G[i].push_back({n, 0});
      } else {
        ld d = INF;
        rep(j, vl[i].size()) { d = min(d, dist_sp(vl[i][j], s)); }
        G[n].push_back({i, d});
        G[i].push_back({n, d});
      }
      if (fg) {
        G[n + 1].push_back({i, 0});
        G[i].push_back({n + 1, 0});
      } else {
        ld d = INF;
        rep(j, vl[i].size()) { d = min(d, dist_sp(vl[i][j], g)); }
        G[n + 1].push_back({i, d});
        G[i].push_back({n + 1, d});
      }
    }
    G[n].push_back({n + 1, abs(g - s)});
    G[n + 1].push_back({n, abs(g - s)});
    fill(dist, dist + n + 2, INF);
    dist[n] = 0;
    q.push({0, n});
    while (!q.empty()) {
      speP p = q.top();
      q.pop();
      int id = p.second;
      if (p.first > dist[id])
        continue;
      rep(j, G[id].size()) {
        int to = G[id][j].to;
        ld nd = G[id][j].cost + p.first;
        if (nd < dist[to]) {
          dist[to] = nd;
          q.push({nd, to});
        }
      }
    }
    cout << dist[n + 1] << endl;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  // stop
  return 0;
}