Problem p00833 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;

using ll = long long;
inline int sgn(const ll &r) { return (r > 0) - (r < 0); }

using P = complex<ll>;
using L = struct {
  P s, t;
};

namespace std {
bool operator>(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) > 0 : sgn(imag(a - b)) > 0;
}
bool operator<(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) < 0 : sgn(imag(a - b)) < 0;
}
bool operator==(const P &a, const P &b) {
  return sgn(real(a - b)) == 0 && sgn(imag(a - b)) == 0;
}
} // namespace std

bool operator<(const L &a, const L &b) {
  return a.s == b.s ? a.t < b.t : a.s < b.s;
}
bool operator==(const L &a, const L &b) { return a.s == b.s && a.t == b.t; }

inline ll dot(P o, P a, P b) {
  a -= o, b -= o;
  return real(conj(a) * b);
}
inline ll det(P o, P a, P b) {
  a -= o, b -= o;
  return imag(conj(a) * b);
}

enum CCW { LEFT = 1, RIGHT = 2, BACK = 4, FRONT = 8, ON = 16 };
inline int ccw(P o, P a, P b) {
  if (sgn(det(o, a, b)) > 0)
    return LEFT; // counter clockwise
  if (sgn(det(o, a, b)) < 0)
    return RIGHT; // clockwise
  if (sgn(dot(o, a, b)) < 0)
    return BACK; // b--base--a on line
  if (sgn(norm(a - o) - norm(b - o)) < 0)
    return FRONT; // base--a--b on line
  return ON;      // base--b--a on line  semnet determination betwenn a and b
}

inline bool cross(L a, L b) {
  if (det(P(0, 0), a.t - a.s, b.t - b.s) != 0)
    return false;
  if ((ccw(a.s, a.t, b.s) & 28) == 0)
    return false;

  using state = tuple<P, int>;

  vector<state> ary = {state(a.s, 0), state(a.t, 0), state(b.s, 1),
                       state(b.t, 1)};
  sort(_all(ary));
  if (get<1>(ary[0]) == get<1>(ary[1]))
    return false;
  if (get<0>(ary[1]) == get<0>(ary[2]))
    return false;
  return true;
}

bool cgraph[10][10];
int color[10];
int dfs(int v, int n, int c) {
  if (v == n)
    return c;
  set<int> used;
  rep(i, v) if (cgraph[v][i]) used.insert(color[i]);

  int ret = 10;
  rep(i, c + 1) {
    if (used.find(i) != used.end())
      continue;
    color[v] = i;
    chmin(ret, dfs(v + 1, n, max(i + 1, c)));
    color[v] = -1;
  }

  return ret;
}

int main(void) {
  int n;
  while (cin >> n, n) {
    set<L> pol[110];
    map<string, vector<int>> conv;
    rep(i, n) {
      string s;
      cin >> s;
      conv[s].push_back(i);

      int x[110], y[110], m = 0;

      while (1) {
        cin >> x[m];
        if (x[m] == -1)
          break;
        cin >> y[m++];
      }

      rep(j, m) {
        P a = P(x[j], y[j]);
        P b = P(x[(j + 1) % m], y[(j + 1) % m]);
        if (a > b)
          swap(a, b);
        pol[i].insert(L({a, b}));
      }
    }

    vector<string> ary;
    for (auto &it : conv)
      ary.push_back(it.first);
    const int m = ary.size();

    bool graph[110][110];
    clr(graph, 0);

    rep(i, n) rep(j, i) {
      for (auto &line : pol[i])
        for (auto &line2 : pol[j]) {
          if (cross(line, line2))
            graph[i][j] = graph[j][i] = true;
        }
    }

    clr(cgraph, 0);
    rep(i, m) rep(j, i) {
      cgraph[i][j] = cgraph[j][i] = false;
      for (auto &v : conv[ary[i]])
        for (auto &v2 : conv[ary[j]])
          if (graph[v][v2])
            cgraph[i][j] = cgraph[j][i] = true;
    }

    // rep(i,m){
    // 	rep(j,m) cout << cgraph[i][j] << " ";
    // 	cout << endl;
    // }
    cout << dfs(0, m, 0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;

using ll = long long;
inline int sgn(const ll &r) { return (r > 0) - (r < 0); }

using P = complex<ll>;
using L = struct {
  P s, t;
};

namespace std {
bool operator>(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) > 0 : sgn(imag(a - b)) > 0;
}
bool operator<(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) < 0 : sgn(imag(a - b)) < 0;
}
bool operator==(const P &a, const P &b) {
  return sgn(real(a - b)) == 0 && sgn(imag(a - b)) == 0;
}
} // namespace std

bool operator<(const L &a, const L &b) {
  return a.s == b.s ? a.t < b.t : a.s < b.s;
}
bool operator==(const L &a, const L &b) { return a.s == b.s && a.t == b.t; }

inline ll dot(P o, P a, P b) {
  a -= o, b -= o;
  return real(conj(a) * b);
}
inline ll det(P o, P a, P b) {
  a -= o, b -= o;
  return imag(conj(a) * b);
}

enum CCW { LEFT = 1, RIGHT = 2, BACK = 4, FRONT = 8, ON = 16 };
inline int ccw(P o, P a, P b) {
  if (sgn(det(o, a, b)) > 0)
    return LEFT; // counter clockwise
  if (sgn(det(o, a, b)) < 0)
    return RIGHT; // clockwise
  if (sgn(dot(o, a, b)) < 0)
    return BACK; // b--base--a on line
  if (sgn(norm(a - o) - norm(b - o)) < 0)
    return FRONT; // base--a--b on line
  return ON;      // base--b--a on line  semnet determination betwenn a and b
}

inline bool cross(L a, L b) {
  if (det(P(0, 0), a.t - a.s, b.t - b.s) != 0)
    return false;
  const int sa = ccw(a.s, a.t, b.s) | ccw(a.s, b.t, b.t);
  const int sb = ccw(b.s, b.t, a.s) | ccw(b.s, b.t, a.t);
  if ((sa & ON) == 0)
    return false;
  if ((sb & ON) == 0)
    return false;

  using state = tuple<P, int>;

  bool ok = true;
  vector<state> ary = {state(a.s, 0), state(a.t, 0), state(b.s, 1),
                       state(b.t, 1)};
  sort(_all(ary));
  if (get<1>(ary[0]) == get<1>(ary[1]))
    return false;
  if (get<1>(ary[2]) == get<1>(ary[3]))
    return false;
  if (get<0>(ary[1]) == get<0>(ary[2]))
    return false;
  // cout << a.s << " " << a.t << " " << b.s << " " << b.t << endl;
  return true;
}

int main(void) {
  int n;
  while (cin >> n, n) {
    set<L> pol[110];
    map<string, vector<int>> conv;
    rep(i, n) {
      string s;
      cin >> s;
      conv[s].push_back(i);

      int x[110], y[110], m = 0;

      while (1) {
        cin >> x[m];
        if (x[m] == -1)
          break;
        cin >> y[m++];
      }

      rep(j, m) {
        P a = P(x[j], y[j]);
        P b = P(x[(j + 1) % m], y[(j + 1) % m]);
        if (a > b)
          swap(a, b);
        pol[i].insert(L({a, b}));
      }
    }

    vector<string> ary;
    for (auto &it : conv)
      ary.push_back(it.first);
    const int m = ary.size();

    bool graph[110][110];
    clr(graph, 0);

    rep(i, n) rep(j, i) {
      bool ok = false;
      for (auto &line : pol[i])
        for (auto &line2 : pol[j]) {
          if (ok)
            continue;
          if (cross(line, line2))
            ok = true;
        }
      if (ok)
        graph[i][j] = graph[j][i] = true;
    }

    int index[10];
    iota(index, index + m, 0);

    int ans = 10;

    do {
      int color[110];
      clr(color, -1);

      rep(i, m) {
        string s = ary[i];
        set<int> used;
        for (auto &v : conv[s])
          rep(v2, n) if (graph[v][v2]) used.insert(color[v2]);
        int cmax = 0;
        while (used.find(cmax) != used.end())
          cmax++;
        for (auto &v : conv[s])
          color[v] = cmax;
      }

      int num = 0;
      rep(i, n) chmax(num, color[i]);
      chmin(ans, num + 1);

    } while (next_permutation(index, index + m));

    // rep(i,n){
    // 	rep(j,n) cout << graph[i][j] << " ";
    // 	cout << endl;
    // }

    // const P a=P(10,50),b=P(20,40),c=P(35,25);
    // cout << cross(L({a,b}),L({a,c})) << endl;
    // for(auto &line:pol[2]) for(auto &line2:pol[3]) cout << cross(line,line2)
    // << endl;
    cout << ans << endl;
  }
  return 0;
}