Problem p00833 (C++)

Buggy submission (status: Runtime Error):
// Enjoy your stay.

#include <bits/stdc++.h>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it, X) for (auto it = (X).begin(); it != (X).end(); it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<ll, ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

// geometry library from hos

const double PI = acos(-1);

int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }

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; }
  bool operator<(const Pt &a) const { return x < a.x || x == a.x && y < a.y; }
  bool operator==(const Pt &a) const { return x == a.x && y == a.y; }
  bool operator!=(const Pt &a) const { return x != a.x || y != a.y; }
};

ostream &operator<<(ostream &os, const Pt &a) {
  os << "(" << a.x << ", " << a.y << ")";
  return os;
}

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; // +1 or -1
  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;
}

// end of library from hos

int iSP2(Pt a, Pt b, Pt c) {
  int s = sig((b - a).det(c - a));
  if (s)
    return s; // +1 or -1
  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;
}

double area(vector<Pt> p) {
  double res = 0;
  rep(i, sz(p)) { res += p[i].det(p[(i + 1) % sz(p)]); }
  return res / 2;
}

int n;
map<string, vector<vector<Pt>>> M;
string name[11];
int g[11][11];
int ok[1 << 11];
int dp[1 << 11];

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);

  while (cin >> n && n) {
    M.clear();
    memset(g, 0, sizeof(g));
    rep(i, n) {
      string s;
      cin >> s;
      vector<Pt> p;
      int x, y;
      while (cin >> x && x != -1) {
        cin >> y;
        p.pb(Pt(x, y));
      }
      if (area(p) < 0) {
        reverse(p.begin(), p.end());
      }
      M[s].pb(p);
    }

    int c = 0;
    foreach (it, M) {
      name[c++] = it->fir;
    }

    rep(I, c) rep2(J, I + 1, c) {
      auto &v1 = M[name[I]], &v2 = M[name[J]];
      rep(i, sz(v1)) rep(j, sz(v2)) rep(ii, sz(v1[i])) rep(jj, sz(v2[j])) {
        int res1 = iSP2(v1[i][ii], v1[i][(ii + 1) % sz(v1[i])], v2[j][jj]);
        int res2 = iSP2(v1[i][ii], v1[i][(ii + 1) % sz(v1[i])],
                        v2[j][(jj + 1) % sz(v2[j])]);
        if (res1 > res2)
          swap(res1, res2);
        if ((res1 == -2 || res1 == 0) && (res2 == 0 || res2 == +2)) {
          // cout<<name[I]<<" "<<name[J]<<" "<<v1[i][ii]<<" "<<v1[i][(ii+1) %
          // sz(v1[i])]<<" "<<v2[j][jj]<<" "<<v2[j][(jj+1) % sz(v2[j])]<<endl;
          g[I][J] = g[J][I] = 1;
          goto end;
        }
      }
    end:;
    }

    /*rep(i,c)rep(j,c){
            cout<<g[i][j]<<" ";if(j==c-1)cout<<endl;
    }*/

    rep(i, 1 << c) ok[i] = 1, dp[i] = INF;
    dp[0] = 0;
    rep(mask, 1 << c) {
      rep(i, n) if (mask >> i & 1) rep(j, n) if (mask >> j & 1) {
        if (g[i][j])
          ok[mask] = 0;
      }
    }

    rep(mask, 1 << c) {
      rep(sub, 1 << c) if ((mask & sub) == sub && ok[sub]) {
        dp[mask] = min(dp[mask], dp[mask ^ sub] + 1);
      }
    }
    cout << dp[(1 << c) - 1] << endl;
  }
}

Fixed submission:
// Enjoy your stay.

#include <bits/stdc++.h>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it, X) for (auto it = (X).begin(); it != (X).end(); it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<ll, ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

// geometry library from hos

const double PI = acos(-1);

int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }

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; }
  bool operator<(const Pt &a) const { return x < a.x || x == a.x && y < a.y; }
  bool operator==(const Pt &a) const { return x == a.x && y == a.y; }
  bool operator!=(const Pt &a) const { return x != a.x || y != a.y; }
};

ostream &operator<<(ostream &os, const Pt &a) {
  os << "(" << a.x << ", " << a.y << ")";
  return os;
}

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; // +1 or -1
  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;
}

// end of library from hos

int iSP2(Pt a, Pt b, Pt c) {
  int s = sig((b - a).det(c - a));
  if (s)
    return s; // +1 or -1
  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;
}

double area(vector<Pt> p) {
  double res = 0;
  rep(i, sz(p)) { res += p[i].det(p[(i + 1) % sz(p)]); }
  return res / 2;
}

int n;
map<string, vector<vector<Pt>>> M;
string name[11];
int g[11][11];
int ok[1 << 11];
int dp[1 << 11];

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);

  while (cin >> n && n) {
    M.clear();
    memset(g, 0, sizeof(g));
    rep(i, n) {
      string s;
      cin >> s;
      vector<Pt> p;
      int x, y;
      while (cin >> x && x != -1) {
        cin >> y;
        p.pb(Pt(x, y));
      }
      if (area(p) < 0) {
        reverse(p.begin(), p.end());
      }
      M[s].pb(p);
    }

    int c = 0;
    foreach (it, M) {
      name[c++] = it->fir;
    }

    rep(I, c) rep2(J, I + 1, c) {
      auto &v1 = M[name[I]], &v2 = M[name[J]];
      rep(i, sz(v1)) rep(j, sz(v2)) rep(ii, sz(v1[i])) rep(jj, sz(v2[j])) {
        int res1 = iSP2(v1[i][ii], v1[i][(ii + 1) % sz(v1[i])], v2[j][jj]);
        int res2 = iSP2(v1[i][ii], v1[i][(ii + 1) % sz(v1[i])],
                        v2[j][(jj + 1) % sz(v2[j])]);
        if (res1 > res2)
          swap(res1, res2);
        if ((res1 == -2 || res1 == 0) && (res2 == 0 || res2 == +2)) {
          // cout<<name[I]<<" "<<name[J]<<" "<<v1[i][ii]<<" "<<v1[i][(ii+1) %
          // sz(v1[i])]<<" "<<v2[j][jj]<<" "<<v2[j][(jj+1) % sz(v2[j])]<<endl;
          g[I][J] = g[J][I] = 1;
          goto end;
        }
      }
    end:;
    }

    /*rep(i,c)rep(j,c){
            cout<<g[i][j]<<" ";if(j==c-1)cout<<endl;
    }*/

    rep(i, 1 << c) ok[i] = 1, dp[i] = INF;
    dp[0] = 0;
    rep(mask, 1 << c) {
      rep(i, c) if (mask >> i & 1) rep(j, c) if (mask >> j & 1) {
        if (g[i][j])
          ok[mask] = 0;
      }
    }

    rep(mask, 1 << c) {
      rep(sub, 1 << c) if ((mask & sub) == sub && ok[sub]) {
        dp[mask] = min(dp[mask], dp[mask ^ sub] + 1);
      }
    }
    cout << dp[(1 << c) - 1] << endl;
  }
}