Problem p00833 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(a) (a).begin(), (a).end()
#define fs first
#define sc second
#define pb push_back
#define sz size()

using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> L;
typedef vector<int> vi;

inline int dot(const P &a, const P &b) { return a.fs * b.fs + a.sc * b.sc; }
inline int cross(const P &a, const P &b) { return a.fs * b.sc - a.sc * b.fs; }
inline int norm(const P &a) { return a.fs * a.fs + a.sc * a.sc; }

inline int ccw(const P &a, P b, P c) {
  b.fs -= a.fs;
  b.sc -= a.sc;
  c.fs -= a.fs;
  c.sc -= a.sc;
  if (cross(b, c) > 0)
    return 2;
  if (cross(b, c) < 0)
    return -2;
  if (dot(b, c) < 0)
    return 1;
  if (norm(b) < norm(c))
    return -1;
  return 0;
}

vector<vi> g;
vi cols;
int n, m, ans;

void dfs(int d, int num, const int &clique) {
  if (num >= ans || num >= m)
    return;
  if (d == m) {
    ans = num;
    return;
  }
  if ((clique >> d) & 1) {
    dfs(d + 1, num, clique);
    return;
  }

  vi use(num, 0);
  rep(i, m) {
    if (i < d || (clique >> i) & 1) {
      if (g[d][i])
        use[cols[i]] = 1;
    }
  }

  rep(i, num) {
    if (!use[i]) {
      cols[d] = i;
      dfs(d + 1, num, clique);
      if (num >= ans)
        return;
    }
  }

  cols[d] = num;
  dfs(d, num + 1, clique);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  while (cin >> n) {
    if (n == 0)
      break;

    map<string, int> country;
    vi id(n);
    vector<vector<L>> poly(n);

    m = 0;
    rep(i, n) {
      string name;
      cin >> name;

      if (country.find(name) == country.end()) {
        country[name] = m++;
      }
      id[i] = country[name];

      int x, y;
      vector<P> points;

      for (;;) {
        cin >> x;
        if (x < 0)
          break;
        cin >> y;
        points.pb(P(x, y));
      }

      rep(j, points.sz) {
        poly[i].pb(L(points[j], points[(j + 1) % points.sz]));
        if (poly[i][j].sc < poly[i][j].fs)
          swap(poly[i][j].fs, poly[i][j].sc);
      }
    }

    g = vector<vi>(m, vi(m, 0));

    rep(i, n) rep(j, i) {
      bool f = false;
      for (L a : poly[i]) {
        for (L b : poly[j]) {
          if (abs(ccw(a.fs, a.sc, b.fs)) <= 1 &&
              abs(ccw(a.fs, a.sc, b.sc)) <= 1) {
            if ((b.fs < a.sc && a.fs < b.sc) || (a.fs < b.sc && b.fs < a.sc)) {
              f = true;
              break;
            }
          }
        }
        if (f)
          break;
      }
      if (f)
        g[id[i]][id[j]] = g[id[j]][id[i]] = 1;
    }

    int clique = 1, s = 1;
    for (int bit = 1; bit < (1 << m); bit++) {
      int p = __builtin_popcount(bit);
      if (p <= s)
        continue;
      bool f = true;
      rep(i, m) rep(j, i) {
        if (((bit >> i) & 1) && ((bit >> j) & 1) && !g[i][j])
          f = false;
      }
      if (f) {
        clique = bit;
        s = p;
      }
    }

    cols.resize(m);
    s = 0;
    rep(i, m) {
      if ((clique >> i) & 1)
        cols[i] = s++;
    }

    ans = m;
    dfs(0, s, clique);
    cout << ans << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(a) (a).begin(), (a).end()
#define fs first
#define sc second
#define pb push_back
#define sz size()

using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> L;
typedef vector<int> vi;

inline int dot(const P &a, const P &b) { return a.fs * b.fs + a.sc * b.sc; }
inline int cross(const P &a, const P &b) { return a.fs * b.sc - a.sc * b.fs; }
inline int norm(const P &a) { return a.fs * a.fs + a.sc * a.sc; }

inline int ccw(const P &a, P b, P c) {
  b.fs -= a.fs;
  b.sc -= a.sc;
  c.fs -= a.fs;
  c.sc -= a.sc;
  if (cross(b, c) > 0)
    return 2; // counter clockwise
  if (cross(b, c) < 0)
    return -2; // clockwise
  if (dot(b, c) < 0)
    return 1; // c--a--b on line
  if (norm(b) < norm(c))
    return -1; // a--b--c on line
  return 0;    // on segment
}

vector<vi> g;
vi cols;
int n, m, ans;

void dfs(int d, int num, const int &clique) {
  if (num >= ans || num >= m)
    return;
  if (d == m) {
    ans = num;
    return;
  }
  if ((clique >> d) & 1)
    dfs(d + 1, num, clique);

  vi use(num, 0);
  rep(i, m) {
    if (i < d || (clique >> i) & 1) {
      if (g[d][i])
        use[cols[i]] = 1;
    }
  }

  rep(i, num) {
    if (!use[i]) {
      cols[d] = i;
      dfs(d + 1, num, clique);
      if (num >= ans)
        return;
    }
  }

  cols[d] = num;
  dfs(d, num + 1, clique);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  while (cin >> n) {
    if (n == 0)
      break;

    map<string, int> country;
    vi id(n);
    vector<vector<L>> poly(n);

    m = 0;
    rep(i, n) {
      string name;
      cin >> name;

      if (country.find(name) == country.end()) {
        country[name] = m++;
      }
      id[i] = country[name];

      int x, y;
      vector<P> points;

      for (;;) {
        cin >> x;
        if (x < 0)
          break;
        cin >> y;
        points.pb(P(x, y));
      }

      rep(j, points.sz) {
        poly[i].pb(L(points[j], points[(j + 1) % points.sz]));
        if (poly[i][j].sc < poly[i][j].fs)
          swap(poly[i][j].fs, poly[i][j].sc);
      }
    }

    g = vector<vi>(m, vi(m, 0));

    rep(i, n) rep(j, i) {
      bool f = false;
      for (L a : poly[i]) {
        for (L b : poly[j]) {
          if (abs(ccw(a.fs, a.sc, b.fs)) <= 1 &&
              abs(ccw(a.fs, a.sc, b.sc)) <= 1) {
            if ((b.fs < a.sc && a.fs < b.sc) || (a.fs < b.sc && b.fs < a.sc)) {
              f = true;
              break;
            }
          }
        }
        if (f)
          break;
      }
      if (f)
        g[id[i]][id[j]] = g[id[j]][id[i]] = 1;
    }

    int clique = 1, s = 1;
    for (int bit = 1; bit < (1 << m); bit++) {
      int p = __builtin_popcount(bit);
      if (p <= s)
        continue;
      bool f = true;
      rep(i, m) rep(j, i) {
        if (((bit >> i) & 1) && ((bit >> j) & 1) && !g[i][j])
          f = false;
      }
      if (f) {
        clique = bit;
        s = p;
      }
    }

    cols.resize(m);
    s = 0;
    rep(i, m) {
      if ((clique >> i) & 1)
        cols[i] = s++;
    }

    ans = m;
    dfs(0, s, clique);
    cout << ans << endl;
  }
}