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

#include <bits/stdc++.h>
using namespace std;

struct Point {
  int x, y;
  Point operator+(const Point p) const { return (Point){x + p.x, y + p.y}; }
  Point operator-(const Point p) const { return (Point){x - p.x, y - p.y}; }
};

struct Segment {
  Point p, v;
};

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

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

bool isParallel(Point a, Point b) { return (0 == cross(a, b)); }

int abs(int a) { return max(a, -a); }
bool eq(Point a, Point b) { return (a.x == b.x && a.y == b.y); }
bool eq(Segment a, Segment b) {
  if (eq(a.v, b.v) && eq(a.p, b.p))
    return true;
  if (eq(a.p, b.p + b.v) && eq(a.p + a.v, b.p))
    return true;
  return false;
}

bool onSegment(Segment s, Point p) {
  Point q = p - s.p;
  if (eq(s.p, p) || eq(s.p + s.v, p))
    return false;
  if (!isParallel(s.v, q))
    return false;
  if (dot(s.v, q) <= 0)
    return false;
  Point Q = p - (s.p + s.v);
  if (dot(s.p - s.p - s.v, Q) <= 0)
    return false;
  return true;
}

int n;
int c;
map<string, int> mp;
vector<Segment> G[10];
int g[10][10];

bool calc(int a, int b) {
  for (int i = 0; i < (int)G[a].size(); i++) {
    Segment si = G[a][i];
    for (int j = 0; j < (int)G[b].size(); j++) {
      Segment sj = G[b][j];
      if (!isParallel(si.v, sj.v))
        continue;
      if (eq(si, sj))
        return true;

      if (onSegment(si, sj.p))
        return true;
      if (onSegment(si, sj.p + sj.v))
        return true;
      if (onSegment(sj, si.p))
        return true;
      if (onSegment(sj, si.p + si.v))
        return true;
    }
  }
  return false;
}

void init() {
  c = 0;
  mp.clear();
  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++)
      g[i][j] = 0;
  for (int i = 0; i < 10; i++)
    G[i].clear();
}

int main() {
  int id;
  int px, py;
  string str;
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    init();
    for (int i = 0; i < n; i++) {
      cin >> str;
      if (mp.count(str) == 0)
        mp[str] = id = c++;
      else
        id = mp[str];
      vector<Point> t;
      while (1) {
        cin >> px;
        if (px == -1)
          break;
        cin >> py;
        t.push_back((Point){px, py});
      }
      int size = t.size();
      for (int j = 0; j < size; j++)
        G[id].push_back((Segment){t[j], t[(j + 1) % size] - t[j]});
    }

    for (int i = 0; i + 1 < c; i++) {
      for (int j = i + 1; j < c; j++) {
        bool flg = calc(i, j);
        if (flg)
          g[i][j] = g[j][i] = 1;
      }
    }

    vector<int> e;
    for (int i = 0; i < (1 << c); i++) {
      bool flg = true;
      for (int j = 0; j < c; j++) {
        if (i >> j & 1) {
        } else
          continue;
        for (int k = 0; k < c; k++) {
          if (i >> k & 1) {
          } else
            continue;
          if (g[j][k])
            flg = false;
        }
      }
      if (flg)
        e.push_back(i);
    }

    int dp[(1 << c)];
    fill(dp, dp + (1 << c), 1e8);
    dp[0] = 0;
    for (int S = 0; S < (1 << c); S++) {
      if (dp[S] == 1e8)
        continue;
      for (int i = 0; i < (int)e.size(); i++) {
        int T = e[i];
        dp[S | T] = min(dp[S | T], dp[S] + 1);
      }
    }
    cout << dp[(1 << c) - 1] << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

struct Point {
  int x, y;
  Point operator+(const Point p) const { return (Point){x + p.x, y + p.y}; }
  Point operator-(const Point p) const { return (Point){x - p.x, y - p.y}; }
};

struct Segment {
  Point p, v;
};

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

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

bool isParallel(Point a, Point b) { return (0 == cross(a, b)); }

int abs(int a) { return max(a, -a); }
bool eq(Point a, Point b) { return (a.x == b.x && a.y == b.y); }
bool eq(Segment a, Segment b) {
  if (eq(a.v, b.v) && eq(a.p, b.p))
    return true;
  if (eq(a.p, b.p + b.v) && eq(a.p + a.v, b.p))
    return true;
  return false;
}

bool onSegment(Segment s, Point p) {
  Point q = p - s.p;
  if (eq(s.p, p) || eq(s.p + s.v, p))
    return false;
  if (!isParallel(s.v, q))
    return false;
  if (dot(s.v, q) <= 0)
    return false;
  if (abs(q.x) >= abs(s.v.x))
    return false;
  if (abs(q.y) >= abs(s.v.y))
    return false;
  return true;
}

int n;
int c;
map<string, int> mp;
vector<Segment> G[10];
int g[10][10];

bool calc(int a, int b) {
  for (int i = 0; i < (int)G[a].size(); i++) {
    Segment si = G[a][i];
    for (int j = 0; j < (int)G[b].size(); j++) {
      Segment sj = G[b][j];
      if (!isParallel(si.v, sj.v))
        continue;
      if (eq(si, sj))
        return true;

      if (onSegment(si, sj.p))
        return true;
      if (onSegment(si, sj.p + sj.v))
        return true;
      if (onSegment(sj, si.p))
        return true;
      if (onSegment(sj, si.p + si.v))
        return true;
    }
  }
  return false;
}

void init() {
  c = 0;
  mp.clear();
  for (int i = 0; i < 10; i++) {
    G[i].clear();
    for (int j = 0; j < 10; j++)
      g[i][j] = 0;
  }
}

int main() {
  int id;
  int px, py;
  string str;
  while (1) {
    cin >> n;
    assert(n <= 10);
    if (n == 0)
      break;
    init();
    for (int i = 0; i < n; i++) {
      cin >> str;
      if (mp.count(str) == 0)
        mp[str] = id = c++;
      else
        id = mp[str];
      vector<Point> t;
      while (1) {
        cin >> px;
        if (px == -1)
          break;
        cin >> py;
        t.push_back((Point){px, py});
      }
      int size = t.size();
      for (int j = 0; j < size; j++)
        G[id].push_back((Segment){t[j], t[(j + 1) % size] - t[j]});
    }

    for (int i = 0; i + 1 < c; i++) {
      for (int j = i + 1; j < c; j++) {
        bool flg = calc(i, j);
        if (flg)
          g[i][j] = g[j][i] = 1;
      }
    }

    vector<int> e;
    for (int i = 0; i < (1 << c); i++) {
      bool flg = true;
      for (int j = 0; j < c; j++) {
        if (i >> j & 1) {
        } else
          continue;
        for (int k = 0; k < c; k++) {
          if (i >> k & 1) {
          } else
            continue;
          if (g[j][k])
            flg = false;
        }
      }
      if (flg)
        e.push_back(i);
    }

    int dp[1024];
    fill(dp, dp + 1024, 1e8);
    dp[0] = 0;
    for (int S = 0; S < (1 << c); S++) {
      if (dp[S] == 1e8)
        continue;
      for (int i = 0; i < (int)e.size(); i++) {
        int T = e[i];
        dp[S | T] = min(dp[S | T], dp[S] + 1);
      }
    }
    cout << dp[(1 << c) - 1] << endl;
  }
  return 0;
}