circle minCircle(point P[], int N) { // `1-based` if (N == 1) return circle(P[1], 0.0); random_shuffle(P + 1, P + N + 1); circle O = minCircle(P[1], P[2]); Rep(i, 1, N) if(!O.inside(P[i])) { O = minCircle(P[1], P[i]); Foru(j, 1, i) if(!O.inside(P[j])) { O = minCircle(P[i], P[j]); Foru(k, 1, j) if(!O.inside(P[k])) O = minCircle(P[i], P[j], P[k]); }
inline static std::pair<std::pair<long double, long double>, long double> findCircle(unsigned int s, unsigned int e) { for(unsigned int p = s; p < e; ++ p) sPoint[p] = point[p]; return minCircle(s, e); }
inline static std::pair<std::pair<long double, long double>, long double> minCircle(unsigned int s, unsigned int e, int q1, int q2, int q3) { std::pair<std::pair<long double, long double>, long double> res; std::random_shuffle(sPoint + s, sPoint + e); if(q3 != -1) // GOT A TRIPLE { res.first.first = ((sPoint[q2].first * sPoint[q2].first * sPoint[q3].second + sPoint[q2].second * sPoint[q2].second * sPoint[q3].second - sPoint[q1].first * sPoint[q1].first * sPoint[q3].second + sPoint[q1].first * sPoint[q1].first * sPoint[q2].second - sPoint[q1].second * sPoint[q1].second * sPoint[q3].second + sPoint[q1].second * sPoint[q1].second * sPoint[q2].second + sPoint[q1].second * sPoint[q3].first * sPoint[q3].first + sPoint[q1].second * sPoint[q3].second * sPoint[q3].second - sPoint[q1].second * sPoint[q2].first * sPoint[q2].first - sPoint[q1].second * sPoint[q2].second * sPoint[q2].second - sPoint[q2].second * sPoint[q3].first * sPoint[q3].first - sPoint[q2].second * sPoint[q3].second * sPoint[q3].second) / (sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q2].first - sPoint[q2].second * sPoint[q3].first - sPoint[q3].second * sPoint[q1].first + sPoint[q3].second * sPoint[q2].first + sPoint[q2].second * sPoint[q1].first)) / 2; res.first.second = ((-sPoint[q1].first * sPoint[q3].first * sPoint[q3].first - sPoint[q1].first * sPoint[q3].second * sPoint[q3].second + sPoint[q1].first * sPoint[q2].first * sPoint[q2].first + sPoint[q1].first * sPoint[q2].second * sPoint[q2].second + sPoint[q2].first * sPoint[q3].first * sPoint[q3].first + sPoint[q2].first * sPoint[q3].second * sPoint[q3].second - sPoint[q2].first * sPoint[q2].first * sPoint[q3].first - sPoint[q2].second * sPoint[q2].second * sPoint[q3].first + sPoint[q1].first * sPoint[q1].first * sPoint[q3].first - sPoint[q1].first * sPoint[q1].first * sPoint[q2].first + sPoint[q1].second * sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q1].second * sPoint[q2].first) / (sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q2].first - sPoint[q2].second * sPoint[q3].first - sPoint[q3].second * sPoint[q1].first + sPoint[q3].second * sPoint[q2].first + sPoint[q2].second * sPoint[q1].first)) / 2; res.second = dist(res.first, sPoint[q2]); return res; } else if(q2 != -1) { res.first = std::make_pair( (sPoint[q1].first + sPoint[q2].first) / 2, (sPoint[q1].second + sPoint[q2].second) / 2 ); res.second = dist(res.first, sPoint[q1]); } else if(q1 != -1) { res.first = std::make_pair( (sPoint[q1].first + sPoint[s].first) / 2, (sPoint[q1].second + sPoint[s].second) / 2 ); res.second = dist(res.first, sPoint[q1]); if(e == s + 1) return res; } else if(e == s + 1) { res.first = sPoint[s]; res.second = 0; return res; } else { res.first = std::make_pair( (sPoint[s].first + sPoint[s + 1].first) / 2, (sPoint[s].second + sPoint[s + 1].second) / 2 ); res.second = dist(res.first, sPoint[s]); } for(unsigned int p = s; p < e; ++ p) { if(inCircle(res, sPoint[p])) continue; if(q2 != -1) res = minCircle(s, p, q1, q2, p); else if(q1 != -1) res = minCircle(s, p, q1, p); else res = minCircle(s, p, p); } return res; }