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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define IINF (INT_MAX)
#define EPS (1e-10)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define MAX 20

using namespace std;

typedef pair<int, int> ii;

// Library - template - begin

class Point {
public:
  double x, y;

  Point(double x = -IINF, double y = -IINF) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(a * x, a * y); }
  Point operator/(double a) { return Point(x / a, y / a); }
  Point operator*(Point a) {
    return Point(x * a.x - y * a.y, x * a.y + y * a.x);
  }

  bool operator<(const Point &p) const {
    return !equals(x, p.x) ? x < p.x : y < p.y;
  }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
  bool operator==(const Segment &p) const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

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

ostream &operator<<(ostream &os, const Segment &a) {
  os << "( " << a.p1 << " , " << a.p2 << " )";
}

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double abs(Point a) { return sqrt(norm(a)); }

// rad は角度をラジアンで持たせること
Point rotate(Point a, double rad) {
  return Point(cos(rad) * a.x - sin(rad) * a.y,
               sin(rad) * a.x + cos(rad) * a.y);
}

// 度をラジアンに変換
double toRad(double agl) { return agl * M_PI / 180.0; }

// Library - template - end

// Library - CCW - begin

int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > EPS)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

// Library - CCW - end

// Library - intersect - begin

bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2 - l.p1, m.p2 - m.p1)) > EPS || // non-parallel
         abs(cross(l.p2 - l.p1, m.p1 - l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2 - l.p1, s.p1 - l.p1) * // s[0] is left of l
             cross(l.p2 - l.p1, s.p2 - l.p1) <
         EPS; // s[1] is right of l
}
bool intersectLP(Line l, Point p) {
  return abs(cross(l.p2 - p, l.p1 - p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 &&
         ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1 - p) + abs(s.p2 - p) - abs(s.p2 - s.p1) <
         EPS; // triangle inequality
}

Point projection(Line l, Point p) {
  double t = dot(p - l.p1, l.p1 - l.p2) / norm(l.p1 - l.p2);
  return l.p1 + (l.p1 - l.p2) * t;
}
Point reflection(Line l, Point p) { return p + (projection(l, p) - p) * 2; }
double distanceLP(Line l, Point p) { return abs(p - projection(l, p)); }
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}
Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS)
    return m.p1; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.p1 + (m.p2 - m.p1) * (B / A);
}

// Library - intersect - end

// Library - Dent - begin

int pow(int x, int n) {
  int res = 1;
  for (; n; n >>= 1) {
    if (n & 1)
      res = res * x;
    x = x * x;
  }
  return res;
}

int chromatic_number(vector<vector<int>> &M) {
  int n = M.size();
  vector<int> F(n);
  rep(i, n) {
    F[i] |= 1 << i;
    rep(j, n) {
      if (M[i][j])
        F[i] |= 1 << j;
    }
  }

  vector<int> I(1 << n);
  I[0] = 1;
  for (int i = 1; i < (1 << n); i++) {
    int v = __builtin_ctz(i);
    I[i] = I[i ^ (1 << v)] + I[i & ~F[v]];
  }
  int low = 0, high = n;
  while (low + 1 < high) {
    int k = (low + high) / 2, g = 0;
    rep(i, (1 << n)) {
      if (__builtin_popcount(i) & 1) {
        g -= pow(I[i], k);
      } else {
        g += pow(I[i], k);
      }
    }
    if (g != 0)
      high = k;
    else
      low = k;
  }
  return high;
}

// Library - Dent - end

struct P {
  Point p;
  int type;
  P(Point p = Point(), int type = IINF) : p(p), type(type) {}
  bool operator<(const P &a) const {
    if (!(p == a.p))
      return p < a.p;
    return type < a.type;
  }
};

bool isParallel(Vector a, Vector b) { return equals(cross(a, b), 0.0); }

bool isParallel(Point a1, Point a2, Point b1, Point b2) {
  return isParallel(a1 - a2, b1 - b2);
}

bool isParallel(Segment s1, Segment s2) {
  return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

bool intersect(Segment seg1, Segment seg2) {
  if (!isParallel(seg1, seg2))
    return false;

  double dist = distanceSS(seg1, seg2);

  if (!equals(dist, 0.0))
    return false;

  vector<P> vec;

  vec.push_back(P(seg1.p1, 0));
  vec.push_back(P(seg1.p2, 0));
  vec.push_back(P(seg2.p1, 1));
  vec.push_back(P(seg2.p2, 1));
  sort(vec.begin(), vec.end());
  if (vec[1].p == vec[2].p)
    return false;

  return true;
}

vector<int> G[MAX];

int main() {

  int N;
  while (cin >> N, N) {
    map<string, int> Index;
    int dex = 0;
    string country[N];
    vector<Point> coor[N];
    int index[N];

    rep(i, N) {
      cin >> country[i];
      if (Index.find(country[i]) == Index.end())
        Index[country[i]] = dex++;
      int x, y;
      while (cin >> x, x != -1) {
        cin >> y;
        coor[i].push_back(Point(x, y));
      }
    }

    rep(i, N) {
      index[i] = Index[country[i]];
      // cout << "index[" << i << "] = " << index[i] << endl;
    }
    int n = Index.size();
    rep(i, n) G[i].clear();

    set<ii> used;

    rep(i, N) {
      REP(j, i + 1, N) {
        if (index[i] == index[j])
          continue;
        if (used.find(ii(index[i], index[j])) != used.end())
          continue;

        vector<Point> vec;
        bool check = false;

        rep(k, coor[i].size()) {
          Segment seg1 = Segment(coor[i][k], coor[i][(k + 1) % coor[i].size()]);
          rep(l, coor[j].size()) {
            Segment seg2 =
                Segment(coor[j][l], coor[j][(l + 1) % coor[j].size()]);

            if (intersect(seg1, seg2)) {
              check = true;
              goto Skip;
            }
          }
        }
      Skip:;
        if (check) {
          used.insert(ii(index[i], index[j]));
          used.insert(ii(index[j], index[i]));
          G[index[i]].push_back(index[j]);
          G[index[j]].push_back(index[i]);
        }
      }
    }
    /*
    cout << "Graph === " << endl;
    rep(i,n)
      {
        cout << "i = " << i << endl;
        rep(j,G[i].size())
          {
            cout << G[i][j];
          }
        cout << endl;
      }
    */
    vector<vector<int>> M(n, vector<int>(n, 0));
    // cout << "n = " << n << endl;
    rep(i, n) {
      rep(j, G[i].size()) {
        int to = G[i][j];
        M[i][to] = M[to][i] = 1;
      }
    }
    // cout << "-----------222----" << endl;
    cout << chromatic_number(M) << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#define F first
#define S second
#define EPS (1e-10)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef pair<int, int> P;
typedef vector<P> VP;
typedef vector<VP> VVP;
int n;
map<string, int> Index;
int index;

int getIndex(string name) {
  int pos;
  if (Index.find(name) == Index.end())
    Index[name] = index, pos = index++;
  else
    pos = Index[name];
  return pos;
}

double dot(P a, P b) { return a.F * b.F + a.S * b.S; }

double cross(P a, P b) { return a.F * b.S - a.S * b.F; }

double norm(P a) { return a.F * a.F + a.S * a.S; }

P operator-(P &a, P &b) { return P(a.F - b.F, a.S - b.S); }

int ccw(P p0, P p1, P p2) {
  P a = p1 - p0;
  P b = p2 - p0;
  if (cross(a, b) > 0)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < 0)
    return CLOCKWISE;
  if (dot(a, b) < 0)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool cmp(const pair<int, int> &a, const pair<int, int> &b) {
  if (a.first != b.first)
    return a.first < b.first;
  return a.second < b.second;
}

vector<pair<int, int>> AndrewScan(vector<pair<int, int>> G2) {
  if (G2.size() < 3)
    return G2;
  vector<pair<int, int>> U, L;
  sort(G2.begin(), G2.end(), cmp);
  int G2_size = G2.size();

  U.push_back(G2[0]);
  U.push_back(G2[1]);
  L.push_back(G2[G2_size - 1]);
  L.push_back(G2[G2_size - 2]);

  for (int i = 2; i < G2_size; i++) {
    for (int j = U.size();
         j >= 2 && ccw(U[j - 2], U[j - 1], G2[i]) != CLOCKWISE; j--)
      U.pop_back();
    U.push_back(G2[i]);
  }

  for (int i = G2_size - 3; i >= 0; i--) {
    for (int j = L.size();
         j >= 2 && ccw(L[j - 2], L[j - 1], G2[i]) != CLOCKWISE; j--)
      L.pop_back();
    L.push_back(G2[i]);
  }
  reverse(L.begin(), L.end());
  for (int i = U.size() - 2; i >= 1; i--)
    L.push_back(U[i]);
  return L;
}

bool isIntersect(P p1, P p2, P p3, P p4) {

  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

int Welch_Powell(vector<vector<int>> &G2) {

  bool Empti = true;
  for (int i = 0; i < G2.size(); i++)
    if (G2[i].size() != 0) {
      Empti = false;
      break;
    }
  if (Empti)
    return 1;
  int G2_size = G2.size();
  int PC = 0;
  int chromatic_number = 0;
  bool Drew[G2_size];
  vector<pair<int, int>> Degree;
  for (int i = 0; i < G2_size; i++)
    Drew[i] = false, Degree.push_back(pair<int, int>(G2[i].size(), i));
  sort(Degree.begin(), Degree.end(), greater<pair<int, int>>());
  while (PC < G2_size) {
    chromatic_number++;
    bool Draw[G2_size];
    for (int i = 0; i < G2_size; i++)
      Draw[i] = Drew[i];
    for (int i = 0; i < G2_size; i++) {
      if (Draw[Degree[i].second])
        continue;
      Drew[Degree[i].second] = Draw[Degree[i].second] = true;
      PC++;
      int index = Degree[i].second;
      for (int j = 0; j < G2[index].size(); j++)
        Draw[G2[index][j]] = true;
    }
  }
  return chromatic_number;
}

void printVVI(VVI &G) {
  cout << "printVVI -- " << endl;
  for (int i = 0; i < G.size(); i++) {
    for (int j = 0; j < G[i].size(); j++) {
      cout << G[i][j] << " ";
    }
    cout << endl;
  }
  cout << endl;
}

void printVVP(VVP &G) {
  cout << "printVVP ---- " << endl;
  for (int i = 0; i < G.size(); i++) {
    for (int j = 0; j < G[i].size(); j++) {
      cout << "(" << G[i][j].F << "," << G[i][j].S << ") ";
    }
    cout << endl;
  }
  cout << endl;
}

bool isParallel(P a, P b) { return fabs(cross(a, b) - 0.0) < EPS; }

bool isParallel(P a1, P a2, P b1, P b2) { return isParallel(a1 - a2, b1 - b2); }

bool Not(P a, P b, P c) {
  if (ccw(a, b, c) == CLOCKWISE || ccw(a, b, c) == COUNTER_CLOCKWISE)
    return false;
  return true;
}

bool check(P a, P b, P c, P d) {
  if (!Not(a, b, c) || !Not(a, b, c))
    return false;
  if (ccw(a, b, c) == 0 && ccw(a, b, d) == 0)
    return true;
  if (ccw(a, b, c) == 0 || ccw(a, b, d) == 0)
    return false;
  return true;
  // if((a == c) && (ccw(a,b,d) == ONLINE_FRONT || ccw(a,b,d) ==
  // ON_SEGMENT))return true; if((a == d) && (ccw(a,b,c) == ONLINE_FRONT ||
  // ccw(a,b,c) == ON_SEGMENT))return true; if((b == d) && (ccw(a,b,c) ==
  // ONLINE_FRONT || ccw(a,b,c) == ON_SEGMENT))return true; if((b == c) &&
  // (ccw(a,b,d) == ONLINE_FRONT || ccw(a,b,d) == ON_SEGMENT))return true;

  return false;
}

void printP(P p) { cout << "(" << p.F << "," << p.S << ") " << endl; }

void printCCW(P a, P b, P c) {
  int res = ccw(a, b, c);
  if (res == 1)
    cout << "COUNTER_CLOCKWISE" << endl;
  else if (res == -1)
    cout << "CLOCKWISE" << endl;
  else if (res == 2)
    cout << "ONLINE_BACK" << endl;
  else if (res == -2)
    cout << "ONLINE_FRONT" << endl;
  else
    cout << "ON_SEGMENT" << endl;
}

int main() {
  while (cin >> n, n) {
    index = 0;
    Index.clear();
    VVP PG(n);
    vector<string> NameList(n);
    for (int i = 0; i < n; i++) {
      cin >> NameList[i];

      while (true) {
        P p;
        cin >> p.first;
        if (p.first == -1)
          break;
        cin >> p.second;
        PG[i].push_back(p);
      }
    }

    VVI G;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < PG[i].size(); j++) {
        for (int k = 0; k < n; k++) {
          if (k == i)
            continue;
          int Ikey = getIndex(NameList[i]);
          int Kkey = getIndex(NameList[k]);
          if (Ikey == Kkey)
            continue;

          for (int l = 0; l < PG[k].size(); l++) {
            int kmod = PG[k].size();
            int imod = PG[i].size();
            P a, b, c, d;
            a = PG[i][j];
            b = PG[i][(j + 1) % imod];
            c = PG[k][l];
            d = PG[k][(l + 1) % kmod];

            if (isIntersect(a, b, c, d) && isParallel(a, b, c, d) &&
                check(a, b, c, d)) {
              // cout << "OK! "<< Ikey << ".pb " << Kkey << endl;
              // printP(a);printP(b);printP(c); printP(d);
              // cout << "ccw(a,b,c) = ";
              // printCCW(a,b,c);
              // cout << "ccw(a,b,d) = ";
              // printCCW(a,b,d);
              if (Ikey >= G.size()) {
                G.push_back(vector<int>());
                if (G.size() <= Ikey) {
                  cerr << "G.size() = " << G.size() << endl;
                  cerr << "Ikey = " << Ikey << endl;
                  assert(G.size() <= Ikey);
                }
                G[Ikey].push_back(Kkey);
              } else
                G[Ikey].push_back(Kkey);

              break;
            }
          }
        }
      }
    }

    for (int i = 0; i < G.size(); i++) {
      sort(G[i].begin(), G[i].end());
      G[i].erase(unique(G[i].begin(), G[i].end()), G[i].end());
    }

    // printVVI(G);
    cout << Welch_Powell(G) << endl;
  }
  return 0;
}