Problem p01709 (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
}
int sz[40];
int g[40][40];
vector<Pt> p[40];
int deg[40];
int col;
int now[40];
int n;
int nd;
int dfs(int a) {
  if (a == nd)
    return 1;
  int nx = -1;
  int ch = 0;
  int re = 0;
  int me = 0;
  for (int i = 0; i < n; i++) {
    if (~now[i])
      continue;
    if (col == 3 && deg[i] < 3)
      continue;
    int mask = 0;
    int ef = 0;
    for (int j = 0; j < n; j++) {
      if (g[i][j]) {
        if (~now[j])
          mask |= (1 << now[j]);
        else
          ef++;
      }
    }
    int nch = __builtin_popcount(mask);
    if (nch == col)
      return 0;
    if (nch > ch || (nch == ch && me < ef)) {
      nx = i;
      ch = nch;
      me = ef;
      re = mask;
    }
  }
  for (int i = 0; i < col; i++) {
    if (re & (1 << i))
      continue;
    now[nx] = i;
    if (dfs(a + 1))
      return 1;
  }
  now[nx] = -1;
  return 0;
}
int main() {
  int a;
  while (scanf("%d", &a), a) {
    n = a;
    for (int i = 0; i < a; i++) {
      p[i].clear();
      int b;
      scanf("%d", &b);
      sz[i] = b;
      for (int j = 0; j < b; j++) {
        int x, y;
        scanf("%d%d", &x, &y);
        p[i].push_back(Pt(x, y));
      }
      p[i].push_back(p[i][0]);
    }
    for (int i = 0; i < a; i++)
      deg[i] = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++)
      for (int j = i + 1; j < a; j++) {
        bool ok = false;
        for (int k = 0; k < sz[i]; k++)
          for (int l = 0; l < sz[j]; l++) {
            if (iLL(p[i][k], p[i][k + 1], p[j][l], p[j][l + 1]) != -1)
              continue;
            if (iSP(p[i][k], p[j][l], p[i][k + 1]) == 2)
              ok = true;
            if (iSP(p[i][k], p[j][l + 1], p[i][k + 1]) == 2)
              ok = true;
            if (iSP(p[j][l], p[i][k], p[j][l + 1]) == 2)
              ok = true;
            if (iSP(p[j][l], p[i][k + 1], p[j][l + 1]) == 2)
              ok = true;
            if ((p[i][k] - p[j][l]).ABS() < EPS &&
                (p[i][k + 1] - p[j][l + 1]).ABS() < EPS)
              ok = true;
            if ((p[i][k] - p[j][l + 1]).ABS() < EPS &&
                (p[i][k + 1] - p[j][l]).ABS() < EPS)
              ok = true;
          }
        if (ok) {
          g[i][j] = g[j][i] = 1;
          deg[i]++;
          deg[j]++;
        }
      }
    int ans = 4;
    for (int i = 1; i < 4; i++) {
      col = i;
      for (int j = 0; j < a; j++)
        now[j] = -1;
      nd = n;
      if (i == 3) {
        for (int j = 0; j < a; j++)
          if (deg[j] < 3)
            nd--;
      }
      if (dfs(0)) {
        ans = i;
        break;
      }
    }
    printf("%d\\n", ans);
  }
}

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
}
int sz[40];
int g[40][40];
vector<Pt> p[40];
int deg[40];
int col;
int now[40];
int n;
int dfs(int a) {
  if (a == n)
    return 1;
  int nx = -1;
  int ch = 0;
  int re = 0;
  int me = 0;
  for (int i = 0; i < n; i++) {
    if (~now[i])
      continue;
    int mask = 0;
    int ef = 0;
    for (int j = 0; j < n; j++) {
      if (g[i][j]) {
        if (~now[j])
          mask |= (1 << now[j]);
        else
          ef++;
      }
    }
    int nch = __builtin_popcount(mask);
    if (nch == col)
      return 0;
    if (nch > ch || (nch == ch && me < ef)) {
      nx = i;
      ch = nch;
      me = ef;
      re = mask;
    }
  }
  for (int i = 0; i < col; i++) {
    if (re & (1 << i))
      continue;
    now[nx] = i;
    if (dfs(a + 1))
      return 1;
  }
  now[nx] = -1;
  return 0;
}
int main() {
  int a;
  while (scanf("%d", &a), a) {
    n = a;
    for (int i = 0; i < a; i++) {
      p[i].clear();
      int b;
      scanf("%d", &b);
      sz[i] = b;
      for (int j = 0; j < b; j++) {
        int x, y;
        scanf("%d%d", &x, &y);
        p[i].push_back(Pt(x, y));
      }
      p[i].push_back(p[i][0]);
    }
    for (int i = 0; i < a; i++)
      deg[i] = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++)
      for (int j = i + 1; j < a; j++) {
        bool ok = false;
        for (int k = 0; k < sz[i]; k++)
          for (int l = 0; l < sz[j]; l++) {
            if (iLL(p[i][k], p[i][k + 1], p[j][l], p[j][l + 1]) != -1)
              continue;
            if (iSP(p[i][k], p[j][l], p[i][k + 1]) == 2)
              ok = true;
            if (iSP(p[i][k], p[j][l + 1], p[i][k + 1]) == 2)
              ok = true;
            if (iSP(p[j][l], p[i][k], p[j][l + 1]) == 2)
              ok = true;
            if (iSP(p[j][l], p[i][k + 1], p[j][l + 1]) == 2)
              ok = true;
            if ((p[i][k] - p[j][l]).ABS() < EPS &&
                (p[i][k + 1] - p[j][l + 1]).ABS() < EPS)
              ok = true;
            if ((p[i][k] - p[j][l + 1]).ABS() < EPS &&
                (p[i][k + 1] - p[j][l]).ABS() < EPS)
              ok = true;
          }
        if (ok) {
          g[i][j] = g[j][i] = 1;
          deg[i]++;
          deg[j]++;
        }
      }
    int ans = 4;
    for (int i = 1; i < 4; i++) {
      col = i;
      for (int j = 0; j < a; j++)
        now[j] = -1;
      if (dfs(0)) {
        ans = i;
        break;
      }
    }
    printf("%d\\n", ans);
  }
}