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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
using namespace std;

using R = long double;
const R EPS = 1e-9;
const R PI = acos(-1.0);
const R INF = 1e10;
inline int sgn(R x) { return (x > EPS) - (x < -EPS); }

using P = complex<R>;
const P O = P(0.0);
using L = struct {
  P s, t;
};
using VP = vector<P>;
using VL = vector<L>;

inline R dot(P o, P a, P b) { return real(conj(a - o) * (b - o)); }
inline R det(P o, P a, P b) { return imag(conj(a - o) * (b - o)); }

inline int sdot(P o, P a, P b) { return sgn(dot(o, a, b)); }
inline int sdet(P o, P a, P b) { return sgn(det(o, a, b)); }

P proj(L l, P p) {
  R u = real((p - l.s) / (l.t - l.s));
  return (1 - u) * l.s + u * l.t;
}

auto &operator>>(istream &is, P &p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}

bool iss(L a, L b) {
  int sa = sdet(a.s, a.t, b.s) * sdet(a.s, a.t, b.t);
  int sb = sdet(b.s, b.t, a.s) * sdet(b.s, b.t, a.t);
  return max(sa, sb) < 0;
}

R dsp(L l, P p) {
  P h = proj(l, p);
  if (sdot(l.s, l.t, p) <= 0)
    h = l.s;
  if (sdot(l.t, l.s, p) <= 0)
    h = l.t;
  return abs(p - h);
}

R dss(L a, L b) {
  return iss(a, b) ? 0
                   : min({dsp(a, b.s), dsp(a, b.t), dsp(b, a.s), dsp(b, a.t)});
}

bool in_polygon(const VP &pol, const P &p) {
  int res = 0;
  auto simag = [](const P &p) { return sgn(imag(p)); };
  rep(i, pol.size()) {
    P a = pol[i], b = pol[(i + 1) % pol.size()];
    if (sdet(p, a, b) == 0 and sdot(p, a, b) <= 0)
      return true;
    bool f = simag(p - a) >= 0, s = simag(p - b) < 0;
    if (simag(b - a) * sdet(a, b, p) == 1 and f == s)
      res += (2 * f - 1);
  }
  return res != 0;
}

VP convex_hull(VP pol) {
  int n = pol.size(), k = 0, t = 1;

  auto cmp_x = [](P a, P b) -> bool {
    int sr = sgn(real(a - b)), si = sgn(imag(a - b));
    return sr ? sr < 0 : si < 0;
  };

  sort(begin(pol), end(pol), cmp_x);
  VP res(2 * n);

  auto push = [&](P p) -> void {
    while (k > t and sdet(res[k - 1], res[k - 2], p) <= -1)
      k--;
    res[k++] = p;
  };

  for_each(begin(pol), end(pol), push);
  t = k;
  for_each(rbegin(pol) + 1, rend(pol), push);
  res.resize(k - 1);
  return res;
}

int main(void) {
  int cnt = 0;
  int n;
  while (cin >> n, n) {
    VP pol[110];
    R h[110];

    rep(i, n) {
      int nv;
      cin >> nv >> h[i];
      pol[i] = VP(nv);
      rep(j, nv) cin >> pol[i][j];
    }

    R theta, phi;
    cin >> theta >> phi;

    theta = theta / 180.0 * PI;
    phi = phi / 180.0 * PI;

    P s, t;
    cin >> s >> t;

    vector<L> buildings[110];
    rep(i, n) {
      int nv = pol[i].size();
      const R d = h[i] / tan(phi);
      rep(j, nv) pol[i].push_back(pol[i][j] - polar(d, theta));
      pol[i] = convex_hull(pol[i]);
      nv = pol[i].size();
      rep(j, nv) buildings[i].push_back(L{pol[i][j], pol[i][(j + 1) % nv]});
    }

    R dist[110][110];
    const int total = n + 2;
    rep(i, total) rep(j, total) dist[i][j] = (i == j) ? 0 : INF;

    rep(i, n) rep(j, i) {
      R cur = INF;
      for (auto &si : buildings[i]) {
        for (auto &sj : buildings[j]) {
          cur = min(cur, dss(si, sj));
        }
      }
      dist[i][j] = dist[j][i] = cur;
    }

    bool st = true;
    rep(i, n) {
      R cur[2] = {INF, INF};
      for (auto &si : buildings[i]) {
        cur[0] = min(cur[0], dsp(si, s));
        cur[1] = min(cur[1], dsp(si, t));
        if (iss(si, L{s, t}))
          st = false;
      }

      if (in_polygon(pol[i], s))
        cur[0] = 0.0;
      if (in_polygon(pol[i], t))
        cur[1] = 0.0;

      dist[n][i] = dist[i][n] = cur[0];
      dist[n + 1][i] = dist[i][n + 1] = cur[1];
    }

    if (st)
      dist[n][n + 1] = abs(s - t);

    cout.precision(20);
    rep(k, total) rep(i, total) rep(j, total) dist[i][j] =
        min(dist[i][j], dist[i][k] + dist[k][j]);
    cout << fixed << dist[n][n + 1] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
using namespace std;

using R = long double;
const R EPS = 1e-9;
const R PI = acos(-1.0);
const R INF = 1e10;
inline int sgn(R x) { return (x > EPS) - (x < -EPS); }

using P = complex<R>;
const P O = P(0.0);
using L = struct {
  P s, t;
};
using VP = vector<P>;
using VL = vector<L>;

inline R dot(P o, P a, P b) { return real(conj(a - o) * (b - o)); }
inline R det(P o, P a, P b) { return imag(conj(a - o) * (b - o)); }

inline int sdot(P o, P a, P b) { return sgn(dot(o, a, b)); }
inline int sdet(P o, P a, P b) { return sgn(det(o, a, b)); }

P proj(L l, P p) {
  R u = real((p - l.s) / (l.t - l.s));
  return (1 - u) * l.s + u * l.t;
}

auto &operator>>(istream &is, P &p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}

bool iss(L a, L b) {
  int sa = sdet(a.s, a.t, b.s) * sdet(a.s, a.t, b.t);
  int sb = sdet(b.s, b.t, a.s) * sdet(b.s, b.t, a.t);
  return max(sa, sb) < 0;
}

R dsp(L l, P p) {
  P h = proj(l, p);
  if (sdot(l.s, l.t, p) <= 0)
    h = l.s;
  if (sdot(l.t, l.s, p) <= 0)
    h = l.t;
  return abs(p - h);
}

R dss(L a, L b) {
  return iss(a, b) ? 0
                   : min({dsp(a, b.s), dsp(a, b.t), dsp(b, a.s), dsp(b, a.t)});
}

bool in_polygon(const VL &pol, const P &p) {
  const int n = pol.size();
  int res = 0;
  rep(i, n) {
    L l = pol[i];
    if (sdet(p, l.s, l.t) == 0 and sdot(p, l.s, l.t) <= 0)
      return true;
    bool f = sgn(imag(p - l.s)) >= 0, s = sgn(imag(p - l.t)) < 0;
    if (sgn(imag(l.t - l.s)) * sdet(l.s, l.t, p) == 1 and f == s)
      res += 2 * f - 1;
  }
  return res != 0;
}

int main(void) {
  int cnt = 0;
  int n;
  while (cin >> n, n) {
    VP pol[110];
    R h[110];

    rep(i, n) {
      int nv;
      cin >> nv >> h[i];
      rep(j, nv) {
        P p;
        cin >> p;
        pol[i].push_back(p);
      }
    }

    R theta, phi;
    cin >> theta >> phi;

    theta = theta / 180.0 * PI;
    phi = phi / 180.0 * PI;

    P s, t;
    cin >> s >> t;

    vector<VL> buildings[110];
    rep(i, n) {
      const int nv = pol[i].size();
      const R d = h[i] / tan(phi);
      rep(j, nv) {
        VL cur;
        VP point;
        point.push_back(pol[i][j]);
        point.push_back(pol[i][(j + 1) % nv]);
        point.push_back(pol[i][(j + 1) % nv] - polar(d, theta));
        point.push_back(pol[i][j] - polar(d, theta));

        rep(k, 4) cur.push_back(L{point[k], point[(k + 1) % 4]});
        buildings[i].push_back(cur);
      }
    }

    R dist[110][110];
    const int total = n + 2;
    rep(i, total) rep(j, total) dist[i][j] = (i == j) ? 0 : INF;

    rep(i, n) rep(j, i) {
      R cur = INF;
      for (auto &vpi : buildings[i]) {
        for (auto &vpj : buildings[j]) {
          for (auto &si : vpi) {
            for (auto &sj : vpj) {
              cur = min(cur, dss(si, sj));
            }
          }
        }
      }
      dist[i][j] = dist[j][i] = cur;
    }

    bool st = true;
    rep(i, n) {
      R cur[2] = {INF, INF};
      for (auto &vpi : buildings[i]) {
        for (auto &si : vpi) {
          cur[0] = min(cur[0], dsp(si, s));
          cur[1] = min(cur[1], dsp(si, t));
          if (iss(si, L{s, t}))
            st = false;
        }
        if (in_polygon(vpi, s))
          cur[0] = 0.0;
        if (in_polygon(vpi, t))
          cur[1] = 0.0;
      }

      dist[n][i] = dist[i][n] = cur[0];
      dist[n + 1][i] = dist[i][n + 1] = cur[1];
    }

    if (st)
      dist[n][n + 1] = abs(s - t);

    cout.precision(20);
    rep(k, total) rep(i, total) rep(j, total) dist[i][j] =
        min(dist[i][j], dist[i][k] + dist[k][j]);
    cout << fixed << dist[n][n + 1] << endl;
  }
  return 0;
}