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

#include <algorithm>
#include <complex>
#include <deque>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <vector>
using namespace std;
double eps = 1e-6;
double x[110];
double y[110];
double px[700];
double py[700];
int ijk[700];
int v[700];
const double EPS = 1e-8;
const double INF = 1e12;
double PI = 3.14159265358;
struct P {
  double x;
  double y;
  P() {}
  P(double X, double Y) {
    x = X;
    y = Y;
  }
  P operator+(const P &a) const { return P(x + a.x, y + a.y); }
  P operator-(const P &a) const { return P(x - a.x, y - a.y); }
  P operator*(const double &a) const { return P(x * a, y * a); }
  /*operator+ (P a){
          return P(x+a.x,y+a.y);
  }
  operator+ (P a){
          return P(x+a.x,y+a.y);
  }*/
};
inline bool operator<(const P &a, const P &b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline double cross(const P &a, const P &b) { return a.x * b.y - a.y * b.x; }
inline double dot(const P &a, const P &b) { return a.x * b.x + a.y * b.y; }

inline int ccw(P a, P b, P c) {
  b = b - a;
  c = c - a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (b.x * b.x + b.y * b.y < c.x * c.x + c.y * c.y)
    return -2; // a--b--c on line
  return 0;
}
#define se second
#define fi first

bool intersectSS(const pair<P, P> &s, const pair<P, P> &t) {
  return ccw(s.fi, s.se, t.fi) * ccw(s.fi, s.se, t.se) <= 0 &&
         ccw(t.fi, t.se, s.fi) * ccw(t.fi, t.se, s.se) <= 0;
}

P pt[700];
P ps[300];
int s[400];
int t[400];
double left[400];
double right[400];
vector<pair<int, int>> g[700];
int UF[700];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int main() {
  int a, b;
  while (scanf("%d%d", &a, &b), a) {
    for (int i = 0; i < 700; i++)
      UF[i] = -1;
    for (int i = 0; i < 700; i++)
      g[i].clear();
    for (int i = 0; i < a; i++)
      scanf("%lf%lf", x + i, y + i);
    for (int i = 0; i < a; i++) {
      double X = cos(1) * x[i] - sin(1) * y[i];
      double Y = sin(1) * x[i] + cos(1) * y[i];
      x[i] = X;
      y[i] = Y;
      ps[i] = P(x[i], y[i]);
    }
    for (int i = 0; i < b; i++) {
      int p, q;
      scanf("%d%d", &p, &q);
      p--;
      q--;
      s[i] = p;
      t[i] = q;
      px[i * 2] = (x[p] + x[q]) / 2 + eps;
      py[i * 2] = (y[p] + y[q]) / 2;
      px[i * 2 + 1] = (x[p] + x[q]) / 2 - eps;
      py[i * 2 + 1] = (y[p] + y[q]) / 2;
      pt[i * 2] = P(px[i * 2], py[i * 2]);
      pt[i * 2 + 1] = P(px[i * 2 + 1], py[i * 2 + 1]);
    }
    deque<pair<int, int>> Q;
    for (int i = 0; i < a; i++) {
      vector<pair<double, pair<int, int>>> vec;
      for (int j = 0; j < b; j++) {
        if (s[j] == i) {
          vec.push_back(make_pair(atan2(y[t[j]] - y[i], x[t[j]] - x[i]),
                                  make_pair(j, t[j])));
        }
        if (t[j] == i) {
          vec.push_back(make_pair(atan2(y[s[j]] - y[i], x[s[j]] - x[i]),
                                  make_pair(j, s[j])));
        }
      }
      std::sort(vec.begin(), vec.end());
      int sz = vec.size();
      for (int j = 0; j < vec.size(); j++) {
        double th = vec[j].first;
        double th2 = vec[(j + 1) % sz].first;
        if (th > th2)
          th2 += 2 * PI;
        if (th2 - th <= PI + EPS)
          continue;
        for (int k = 0; k < 2; k++)
          for (int l = 0; l < 2; l++) {
            if (intersectSS(
                    make_pair(pt[vec[j].second.first * 2 + k],
                              pt[vec[(j + 1) % sz].second.first * 2 + l]),
                    make_pair(ps[i], ps[vec[j].second.second])) &&
                intersectSS(
                    make_pair(pt[vec[j].second.first * 2 + k],
                              pt[vec[(j + 1) % sz].second.first * 2 + l]),
                    make_pair(ps[i], ps[vec[(j + 1) % sz].second.second]))) {
              g[vec[j].second.first * 2 + k].push_back(
                  make_pair(vec[(j + 1) % sz].second.first * 2 + l, 0));
              g[vec[(j + 1) % sz].second.first * 2 + l].push_back(
                  make_pair(vec[j].second.first * 2 + k, 0));
              UNION(vec[j].second.first * 2 + k,
                    vec[(j + 1) % sz].second.first * 2 + l);
            }
          }
      }
    }
    for (int i = 0; i < b * 2; i++) {
      ijk[i] = 999999999;
      v[i] = 0;
      bool OK = true;
      int tt = s[i / 2];
      for (int j = 0; j < b; j++) {
        if (tt == s[j] || tt == t[j])
          continue;
        if (intersectSS(make_pair(ps[tt], ps[tt] + (pt[i] - ps[tt]) * 10000.0),
                        make_pair(ps[s[j]], ps[t[j]]))) {
          OK = false;
          break;
        }
      }
      tt = t[i / 2];
      for (int j = 0; j < b; j++) {
        if (tt == s[j] || tt == t[j])
          continue;
        if (intersectSS(make_pair(ps[tt], ps[tt] + (pt[i] - ps[tt]) * 10000.0),
                        make_pair(ps[s[j]], ps[t[j]]))) {
          OK = false;
          break;
        }
      }

      if (OK) {
        ijk[i] = 0;
        Q.push_back(make_pair(0, i));
      }
      for (int j = i + 1; j < b * 2; j++) {
        int cnt = 0;
        if (FIND(i) == FIND(j))
          continue;
        for (int k = 0; k < b; k++) {
          if (intersectSS(make_pair(ps[s[k]], ps[t[k]]),
                          make_pair(pt[i], pt[j]))) {
            cnt++;
            if (cnt > 1)
              break;
          }
        }
        if (cnt < 2) {
          if (cnt == 0) {
            UNION(i, j);
          }
          g[i].push_back(make_pair(j, cnt));
          g[j].push_back(make_pair(i, cnt));
        }
      }
    }
    while (Q.size()) {
      int cost = -Q.front().first;
      int at = Q.front().second;
      Q.pop_front();
      if (v[at])
        continue;
      v[at] = 1;
      for (int i = 0; i < g[at].size(); i++) {
        if (!v[g[at][i].first] &&
            ijk[g[at][i].first] > cost + g[at][i].second) {
          ijk[g[at][i].first] = cost + g[at][i].second;
          if (g[at][i].second == 1)
            Q.push_back(make_pair(-ijk[g[at][i].first], g[at][i].first));
          else
            Q.push_front(make_pair(-ijk[g[at][i].first], g[at][i].first));
        }
      }
    }
    int ret = 0;
    for (int i = 0; i < b * 2; i++)
      ret = max(ret, ijk[i]);
    printf("%d\\n", ret);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <complex>
#include <deque>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <vector>
using namespace std;
double eps = 1e-6;
double x[110];
double y[110];
double px[700];
double py[700];
int ijk[700];
int v[700];
const double EPS = 1e-8;
const double INF = 1e12;
double PI = 3.14159265358;
struct P {
  double x;
  double y;
  P() {}
  P(double X, double Y) {
    x = X;
    y = Y;
  }
  P operator+(const P &a) const { return P(x + a.x, y + a.y); }
  P operator-(const P &a) const { return P(x - a.x, y - a.y); }
  P operator*(const double &a) const { return P(x * a, y * a); }
  /*operator+ (P a){
          return P(x+a.x,y+a.y);
  }
  operator+ (P a){
          return P(x+a.x,y+a.y);
  }*/
};
inline bool operator<(const P &a, const P &b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline double cross(const P &a, const P &b) { return a.x * b.y - a.y * b.x; }
inline double dot(const P &a, const P &b) { return a.x * b.x + a.y * b.y; }

int ccw(P a, P b, P c) {
  b = b - a;
  c = c - a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (b.x * b.x + b.y * b.y < c.x * c.x + c.y * c.y)
    return -2; // a--b--c on line
  return 0;
}
#define se second
#define fi first

bool intersectSS(const pair<P, P> &s, const pair<P, P> &t) {
  return ccw(s.fi, s.se, t.fi) * ccw(s.fi, s.se, t.se) <= 0 &&
         ccw(t.fi, t.se, s.fi) * ccw(t.fi, t.se, s.se) <= 0;
}

P pt[700];
P ps[300];
int s[400];
int t[400];
double left[400];
double right[400];
vector<pair<int, int>> g[700];
int UF[700];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int main() {
  int a, b;
  while (scanf("%d%d", &a, &b), a) {
    for (int i = 0; i < 700; i++)
      UF[i] = -1;
    for (int i = 0; i < 700; i++)
      g[i].clear();
    for (int i = 0; i < a; i++)
      scanf("%lf%lf", x + i, y + i);
    for (int i = 0; i < a; i++) {
      double X = cos(1) * x[i] - sin(1) * y[i];
      double Y = sin(1) * x[i] + cos(1) * y[i];
      x[i] = X;
      y[i] = Y;
      ps[i] = P(x[i], y[i]);
    }
    for (int i = 0; i < b; i++) {
      int p, q;
      scanf("%d%d", &p, &q);
      p--;
      q--;
      s[i] = p;
      t[i] = q;
      px[i * 2] = (x[p] + x[q]) / 2 + eps;
      py[i * 2] = (y[p] + y[q]) / 2;
      px[i * 2 + 1] = (x[p] + x[q]) / 2 - eps;
      py[i * 2 + 1] = (y[p] + y[q]) / 2;
      pt[i * 2] = P(px[i * 2], py[i * 2]);
      pt[i * 2 + 1] = P(px[i * 2 + 1], py[i * 2 + 1]);
    }
    deque<pair<int, int>> Q;
    for (int i = 0; i < a; i++) {
      vector<pair<double, pair<int, int>>> vec;
      for (int j = 0; j < b; j++) {
        if (s[j] == i) {
          vec.push_back(make_pair(atan2(y[t[j]] - y[i], x[t[j]] - x[i]),
                                  make_pair(j, t[j])));
        }
        if (t[j] == i) {
          vec.push_back(make_pair(atan2(y[s[j]] - y[i], x[s[j]] - x[i]),
                                  make_pair(j, s[j])));
        }
      }
      std::sort(vec.begin(), vec.end());
      int sz = vec.size();
      for (int j = 0; j < vec.size(); j++) {
        double th = vec[j].first;
        double th2 = vec[(j + 1) % sz].first;
        if (th > th2)
          th2 += 2 * PI;
        if (th2 - th <= PI + EPS)
          continue;
        for (int k = 0; k < 2; k++)
          for (int l = 0; l < 2; l++) {
            if (intersectSS(
                    make_pair(pt[vec[j].second.first * 2 + k],
                              pt[vec[(j + 1) % sz].second.first * 2 + l]),
                    make_pair(ps[i], ps[vec[j].second.second])) &&
                intersectSS(
                    make_pair(pt[vec[j].second.first * 2 + k],
                              pt[vec[(j + 1) % sz].second.first * 2 + l]),
                    make_pair(ps[i], ps[vec[(j + 1) % sz].second.second]))) {
              g[vec[j].second.first * 2 + k].push_back(
                  make_pair(vec[(j + 1) % sz].second.first * 2 + l, 0));
              g[vec[(j + 1) % sz].second.first * 2 + l].push_back(
                  make_pair(vec[j].second.first * 2 + k, 0));
              UNION(vec[j].second.first * 2 + k,
                    vec[(j + 1) % sz].second.first * 2 + l);
            }
          }
      }
    }
    for (int i = 0; i < b * 2; i++) {
      ijk[i] = 999999999;
      v[i] = 0;
      bool OK = true;
      int tt = s[i / 2];
      for (int j = 0; j < b; j++) {
        if (tt == s[j] || tt == t[j])
          continue;
        if (intersectSS(make_pair(ps[tt], ps[tt] + (pt[i] - ps[tt]) * 10000.0),
                        make_pair(ps[s[j]], ps[t[j]]))) {
          OK = false;
          break;
        }
      }
      tt = t[i / 2];
      for (int j = 0; j < b; j++) {
        if (tt == s[j] || tt == t[j])
          continue;
        if (intersectSS(make_pair(ps[tt], ps[tt] + (pt[i] - ps[tt]) * 10000.0),
                        make_pair(ps[s[j]], ps[t[j]]))) {
          OK = false;
          break;
        }
      }

      if (OK) {
        ijk[i] = 0;
        Q.push_back(make_pair(0, i));
      }
      for (int j = i + 1; j < b * 2; j++) {
        int cnt = 0;
        if (FIND(i) == FIND(j))
          continue;
        for (int k = 0; k < b; k++) {
          if (intersectSS(make_pair(ps[s[k]], ps[t[k]]),
                          make_pair(pt[i], pt[j]))) {
            cnt++;
            if (cnt > 1)
              break;
          }
        }
        if (cnt < 2) {
          if (cnt == 0) {
            UNION(i, j);
          }
          g[i].push_back(make_pair(j, cnt));
          g[j].push_back(make_pair(i, cnt));
        }
      }
    }
    while (Q.size()) {
      int cost = -Q.front().first;
      int at = Q.front().second;
      Q.pop_front();
      if (v[at])
        continue;
      v[at] = 1;
      for (int i = 0; i < g[at].size(); i++) {
        if (!v[g[at][i].first] &&
            ijk[g[at][i].first] > cost + g[at][i].second) {
          ijk[g[at][i].first] = cost + g[at][i].second;
          if (g[at][i].second == 1)
            Q.push_back(make_pair(-ijk[g[at][i].first], g[at][i].first));
          else
            Q.push_front(make_pair(-ijk[g[at][i].first], g[at][i].first));
        }
      }
    }
    int ret = 0;
    for (int i = 0; i < b * 2; i++)
      ret = max(ret, ijk[i]);
    printf("%d\\n", ret);
  }
}