Problem p00833 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <map>
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
const double EPS = 1e-10;
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); }
  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 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
}
char in[50];
vector<pair<Pt, Pt>> p[12];
double x[120];
double y[120];
int g[20][20];
int col[20];
int n;
int solve(int a, int b) {
  if (a == n)
    return 1;
  for (int i = 1; i <= b; i++) {
    bool ok = true;
    for (int j = 0; j < a; j++)
      if (g[a][j] && col[j] == i)
        ok = false;
    if (ok) {
      col[a] = i;
      int res = solve(a + 1, b);
      if (res)
        return 1;
    }
  }
  return 0;
}
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<string, int> m;
    n = 0;
    for (int i = 0; i < 12; i++)
      p[i].clear();
    for (int i = 0; i < 20; i++)
      for (int j = 0; j < 20; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++) {
      scanf("%s", in);
      string tmp = in;
      int at;
      if (m.count(tmp))
        at = m[tmp];
      else {
        at = n;
        m[tmp] = n++;
      }
      int s = 0;
      while (1) {
        scanf("%lf", x + s);
        if (x[s] < -0.5)
          break;
        scanf("%lf", y + s);
        s++;
      }
      for (int i = 0; i < s; i++) {
        double X = x[i] * cos(1) - y[i] * sin(1);
        double Y = x[i] * sin(1) + y[i] * cos(1);
        x[i] = X;
        y[i] = Y;
      }
      for (int i = 0; i < s; i++) {
        p[at].push_back(
            make_pair(Pt(x[i], y[i]), Pt(x[(i + 1) % s], y[(i + 1) % s])));
      }
    }
    for (int i = 0; i < a; i++) {
      for (int j = i + 1; j < a; j++) {
        bool ok = false;
        for (int k = 0; k < p[i].size(); k++) {
          if (ok)
            break;
          for (int l = 0; l < p[j].size(); l++) {
            if (ok)
              break;
            if (iLL(p[i][k].first, p[i][k].second, p[j][l].first,
                    p[j][l].second) == -1) {
              if (max(p[i][k].first.x, p[i][k].second.x) <
                  EPS + min(p[j][l].first.x, p[j][l].second.x))
                continue;
              if (min(p[i][k].first.x, p[i][k].second.x) + EPS >
                  max(p[j][l].first.x, p[j][l].second.x))
                continue;
              ok = true;
            }
          }
        }
        if (ok)
          g[i][j] = g[j][i] = 1;
      }
    }
    int ans = n;
    for (int i = 1; i < n; i++) {
      for (int j = 0; j < 20; j++)
        col[j] = 0;
      if (solve(0, i)) {
        ans = i;
        break;
      }
    }
    printf("%d\n", ans);
  }
}

Fixed submission:
#include <algorithm>
#include <map>
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
const double EPS = 1e-10;
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); }
  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 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
}
char in[50];
vector<pair<Pt, Pt>> p[12];
double x[120];
double y[120];
int g[20][20];
int col[20];
int n;
int solve(int a, int b) {
  if (a == n)
    return 1;
  for (int i = 1; i <= b; i++) {
    bool ok = true;
    for (int j = 0; j < a; j++)
      if (g[a][j] && col[j] == i)
        ok = false;
    if (ok) {
      col[a] = i;
      int res = solve(a + 1, b);
      if (res)
        return 1;
    }
  }
  return 0;
}
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<string, int> m;
    n = 0;
    for (int i = 0; i < 12; i++)
      p[i].clear();
    for (int i = 0; i < 20; i++)
      for (int j = 0; j < 20; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++) {
      scanf("%s", in);
      string tmp = in;
      int at;
      if (m.count(tmp))
        at = m[tmp];
      else {
        at = n;
        m[tmp] = n++;
      }
      int s = 0;
      while (1) {
        scanf("%lf", x + s);
        if (x[s] < -0.5)
          break;
        scanf("%lf", y + s);
        s++;
      }
      for (int i = 0; i < s; i++) {
        double X = x[i] * cos(1) - y[i] * sin(1);
        double Y = x[i] * sin(1) + y[i] * cos(1);
        x[i] = X;
        y[i] = Y;
      }
      for (int i = 0; i < s; i++) {
        p[at].push_back(
            make_pair(Pt(x[i], y[i]), Pt(x[(i + 1) % s], y[(i + 1) % s])));
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        bool ok = false;
        for (int k = 0; k < p[i].size(); k++) {
          if (ok)
            break;
          for (int l = 0; l < p[j].size(); l++) {
            if (ok)
              break;
            if (iLL(p[i][k].first, p[i][k].second, p[j][l].first,
                    p[j][l].second) == -1) {
              if (max(p[i][k].first.x, p[i][k].second.x) <
                  EPS + min(p[j][l].first.x, p[j][l].second.x))
                continue;
              if (min(p[i][k].first.x, p[i][k].second.x) + EPS >
                  max(p[j][l].first.x, p[j][l].second.x))
                continue;
              ok = true;
            }
          }
        }
        if (ok)
          g[i][j] = g[j][i] = 1;
      }
    }
    int ans = n;
    for (int i = 1; i < n; i++) {
      for (int j = 0; j < 20; j++)
        col[j] = 0;
      if (solve(0, i)) {
        ans = i;
        break;
      }
    }
    printf("%d\n", ans);
  }
}