Problem:
 Score : 600 points    Problem Statement Given are N points (x_i, y_i) in a two-dimensional plane.  Find the minimum radius of a circle such that all the points are inside or on it.      Constraints  2 \leq N \leq 50  0 \leq x_i \leq 1000  0 \leq y_i \leq 1000  The given N points are all different.  The values in input are all integers.         Input Input is given from Standard Input in the following format:  N  x_1  y_1  :  x_N  y_N       Output Print the minimum radius of a circle such that all the N points are inside or on it.  Your output will be considered correct if the absolute or relative error from our answer is at most 10^{-6} .        Sample Input 1 2
0 0
1 0      Sample Output 1 0.500000000000000000  Both points are contained in the circle centered at (0.5,0) with a radius of 0.5 .       Sample Input 2 3
0 0
0 1
1 0      Sample Output 2 0.707106781186497524       Sample Input 3 10
10 9
5 9
2 0
0 0
2 7
3 3
2 5
10 0
3 7
1 9      Sample Output 3 6.726812023536805158  If the absolute or relative error from our answer is at most 10^{-6} , the output will be considered correct.

Solution (Python):
import math
from scipy.optimize import fmin
EPS = 10**-8


class P2():
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.norm2 = (self.x**2 + self.y**2)**0.5

    def __add__(self, other):
        return P2(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return P2(self.x - other.x, self.y - other.y)

    def smul(self, a):
        return P2(self.x * a, self.y * a)

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def det(self, other):
        return self.x * other.y - self.y * other.x


n = int(input())
p = [P2(*map(int, input().split())) for _ in range(n)]

dist = [[(p[i] - p[j]).norm2 for j in range(n)] for i in range(n)]


def func(cp):
    cp = P2(*cp)
    return max((cp - pi).norm2 for pi in p)


res_cp = fmin(func, [500, 500], disp=False)
ans = func(res_cp)
print(ans)

Solution (Python):
import numpy as np
N = int(input())
P = []
for n in range(N):
    x, y = map(int, input().split())
    P.append((x, y))


def dist(p0, p1):
    x0, y0, x1, y1 = p0[0], p0[1], p1[0], p1[1]
    return (x0 - x1) ** 2 + (y0 - y1) ** 2


def f(x, y):
    return max([dist(p, (x, y)) for p in P])


def minfx(y):
    left = 0
    right = 1000
    for _ in range(80):
        left_ = left * (2 / 3) + right * (1 / 3)
        right_ = left*(1/3)+right*(2/3)
        if f(left_, y) <= f(right_, y):
            right = right_
        else:
            left = left_
    x0 = (left + right) / 2
    return f(x0, y)


left = 0
right = 1000
for _ in range(80):
    left_ = left * (2 / 3) + right * (1 / 3)
    right_ = left*(1/3)+right*(2/3)
    if minfx(left_) <= minfx(right_):
        right = right_
    else:
        left = left_
y0 = (left + right) / 2
print(np.sqrt(minfx(y0)))

Solution (Python):
def main():
    n = int(input())
    xy = [list(map(int, input().split())) for _ in [0]*n]

    
    def circle_cross(x1, y1, r1, x2, y2, r2):
        dist_2 = (x1-x2)**2+(y1-y2)**2
        if dist_2 > (r1+r2)**2:
            return None, None, None, None
        a = (dist_2+r1**2-r2**2)/2
        r = (dist_2*(r1**2)-a**2)**0.5
        ans_x1 = ((a*(x1-x2))+(y1-y2)*r)/dist_2
        ans_x2 = ((a*(x1-x2))-(y1-y2)*r)/dist_2
        ans_y1 = ((a*(y1-y2))-(x1-x2)*r)/dist_2
        ans_y2 = ((a*(y1-y2))+(x1-x2)*r)/dist_2
        return ans_x1+x2, ans_y1+y2, ans_x2+x2, ans_y2+y2

    def check(r):
        flag = 0
        point_list = []
        for i in range(n):
            x1, y1 = xy[i]
            for j in range(i+1, n):
                x2, y2 = xy[j]
                if (x1-x2)**2+(y1-y2)**2 <= 4*(r**2)-10**-9:
                    temp = circle_cross(x1, y1, r, x2, y2, r)
                    point_list.append((temp[0], temp[1]))
                    point_list.append((temp[2], temp[3]))
        for i, j in point_list:
            for x, y in xy:
                if (i-x)**2+(j-y)**2 > r**2+10**-9:
                    break
            else:
                return True
        return False

    def b_search(a, b, value, delta):
        while True:
            med = (a+b)/2
            if abs(b-a) < delta:
                if value(a):
                    return a
                else:
                    return b
            elif value(med):
                b = med
            else:
                a = med

    print(b_search(0, 3000, check, 10**-7))


main()

Solution (Python):
import cmath
import math
import os
import random
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
IINF = 10 ** 18
MOD = 10 ** 9 + 7



INF = float("inf")
PI = cmath.pi
TAU = cmath.pi * 2
EPS = 1e-10


class Point:
    """
    2次元空間上の点
    """

    
    CCW_COUNTER_CLOCKWISE = 1
    
    CCW_CLOCKWISE = -1
    
    CCW_ONLINE_BACK = 2
    
    CCW_ONLINE_FRONT = -2
    
    CCW_ON_SEGMENT = 0

    def __init__(self, x: float, y: float):
        self.c = complex(x, y)

    @property
    def x(self):
        return self.c.real

    @property
    def y(self):
        return self.c.imag

    @staticmethod
    def from_complex(c: complex):
        return Point(c.real, c.imag)

    @staticmethod
    def from_polar(r: float, phi: float):
        c = cmath.rect(r, phi)
        return Point(c.real, c.imag)

    def __add__(self, p):
        """
        :param Point p:
        """
        c = self.c + p.c
        return Point(c.real, c.imag)

    def __iadd__(self, p):
        """
        :param Point p:
        """
        self.c += p.c
        return self

    def __sub__(self, p):
        """
        :param Point p:
        """
        c = self.c - p.c
        return Point(c.real, c.imag)

    def __isub__(self, p):
        """
        :param Point p:
        """
        self.c -= p.c
        return self

    def __mul__(self, f: float):
        c = self.c * f
        return Point(c.real, c.imag)

    def __imul__(self, f: float):
        self.c *= f
        return self

    def __truediv__(self, f: float):
        c = self.c / f
        return Point(c.real, c.imag)

    def __itruediv__(self, f: float):
        self.c /= f
        return self

    def __repr__(self):
        return "({}, {})".format(round(self.x, 10), round(self.y, 10))

    def __neg__(self):
        c = -self.c
        return Point(c.real, c.imag)

    def __eq__(self, p):
        return abs(self.c - p.c) < EPS

    def __abs__(self):
        return abs(self.c)

    @staticmethod
    def ccw(a, b, c):
        """
        線分 ab に対する c の位置
        線分上にあるか判定するだけなら on_segment とかのが速い
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=ja
        :param Point a:
        :param Point b:
        :param Point c:
        """
        b = b - a
        c = c - a
        det = b.det(c)
        if det > EPS:
            return Point.CCW_COUNTER_CLOCKWISE
        if det < -EPS:
            return Point.CCW_CLOCKWISE
        if b.dot(c) < -EPS:
            return Point.CCW_ONLINE_BACK
        if c.norm() - b.norm() > EPS:
            return Point.CCW_ONLINE_FRONT
        return Point.CCW_ON_SEGMENT

    def dot(self, p):
        """
        内積
        :param Point p:
        :rtype: float
        """
        return self.x * p.x + self.y * p.y

    def det(self, p):
        """
        外積
        :param Point p:
        :rtype: float
        """
        return self.x * p.y - self.y * p.x

    def dist(self, p):
        """
        距離
        :param Point p:
        :rtype: float
        """
        return abs(self.c - p.c)

    def norm(self):
        """
        原点からの距離
        :rtype: float
        """
        return abs(self.c)

    def phase(self):
        """
        原点からの角度
        :rtype: float
        """
        return cmath.phase(self.c)

    def angle(self, p, q):
        """
        p に向いてる状態から q まで反時計回りに回転するときの角度
        -pi <= ret <= pi
        :param Point p:
        :param Point q:
        :rtype: float
        """
        return (cmath.phase(q.c - self.c) - cmath.phase(p.c - self.c) + PI) % TAU - PI

    def area(self, p, q):
        """
        p, q となす三角形の面積
        :param Point p:
        :param Point q:
        :rtype: float
        """
        return abs((p - self).det(q - self) / 2)

    def projection_point(self, p, q, allow_outer=False):
        """
        線分 pq を通る直線上に垂線をおろしたときの足の座標
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A&lang=ja
        :param Point p:
        :param Point q:
        :param allow_outer: 答えが線分の間になくても OK
        :rtype: Point|None
        """
        diff_q = q - p
        
        r = (self - p).dot(diff_q) / abs(diff_q)
        
        phase = diff_q.phase()

        ret = Point.from_polar(r, phase) + p
        if allow_outer or (p - ret).dot(q - ret) < EPS:
            return ret
        return None

    def reflection_point(self, p, q):
        """
        直線 pq を挟んで反対にある点
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B&lang=ja
        :param Point p:
        :param Point q:
        :rtype: Point
        """
        
        r = abs(self - p)
        
        angle = p.angle(q, self)
        
        angle = (q - p).phase() - angle
        return Point.from_polar(r, angle) + p

    def on_segment(self, p, q, allow_side=True):
        """
        点が線分 pq の上に乗っているか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=ja
        :param Point p:
        :param Point q:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        :rtype: bool
        """
        if not allow_side and (self == p or self == q):
            return False
        
        
        return abs((p - self).det(q - self)) < EPS and (p - self).dot(q - self) < EPS

    @staticmethod
    def circumstance_of(p1, p2, p3):
        """
        外心
        :param Point p1:
        :param Point p2:
        :param Point p3:
        :rtype: Point|None
        """
        if abs((p2 - p1).det(p3 - p1)) < EPS:
            
            return None
        
        a = (p2.x - p3.x) ** 2 + (p2.y - p3.y) ** 2
        b = (p3.x - p1.x) ** 2 + (p3.y - p1.y) ** 2
        c = (p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2
        num = p1 * a * (b + c - a) + p2 * b * (c + a - b) + p3 * c * (a + b - c)
        den = a * (b + c - a) + b * (c + a - b) + c * (a + b - c)
        return num / den


class Line:
    """
    2次元空間上の直線
    """

    def __init__(self, a: float, b: float, c: float):
        """
        直線 ax + by + c = 0
        """
        self.a = a
        self.b = b
        self.c = c

    @staticmethod
    def from_gradient(grad: float, intercept: float):
        """
        直線 y = ax + b
        :param grad: 傾き
        :param intercept: 切片
        :return:
        """
        return Line(grad, -1, intercept)

    @staticmethod
    def from_segment(p1, p2):
        """
        :param Point p1:
        :param Point p2:
        """
        a = p2.y - p1.y
        b = p1.x - p2.x
        c = p2.y * (p2.x - p1.x) - p2.x * (p2.y - p1.y)
        return Line(a, b, c)

    @property
    def gradient(self):
        """
        傾き
        """
        return INF if self.b == 0 else -self.a / self.b

    @property
    def intercept(self):
        """
        切片
        """
        return INF if self.b == 0 else -self.c / self.b

    def is_parallel_to(self, l):
        """
        平行かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Line l:
        """
        
        return abs(Point.from_rect(self.a, self.b).det(Point.from_rect(l.a, l.b))) < EPS

    def is_orthogonal_to(self, l):
        """
        直行しているかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Line l:
        """
        
        return abs(Point.from_rect(self.a, self.b).dot(Point.from_rect(l.a, l.b))) < EPS

    def intersection_point(self, l):
        """
        交差する点
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C&lang=ja
        :param Line l:
        :rtype: Point|None
        """
        a1, b1, c1 = self.a, self.b, self.c
        a2, b2, c2 = l.a, l.b, l.c
        det = a1 * b2 - a2 * b1
        if abs(det) < EPS:
            
            return None
        x = (b1 * c2 - b2 * c1) / det
        y = (a2 * c1 - a1 * c2) / det
        return Point.from_rect(x, y)

    def dist(self, p):
        """
        他の点との最短距離
        :param Point p:
        """
        raise NotImplementedError()

    def has_point(self, p):
        """
        p が直線上に乗っているかどうか
        :param Point p:
        """
        return abs(self.a * p.x + self.b * p.y + self.c) < EPS


class Segment:
    """
    2次元空間上の線分
    """

    def __init__(self, p1, p2):
        """
        :param Point p1:
        :param Point p2:
        """
        self.p1 = p1
        self.p2 = p2

    def norm(self):
        """
        線分の長さ
        """
        return abs(self.p1 - self.p2)

    def phase(self):
        """
        p1 を原点としたときの p2 の角度
        """
        return (self.p2 - self.p1).phase()

    def is_parallel_to(self, s):
        """
        平行かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Segment s:
        :return:
        """
        
        return abs((self.p1 - self.p2).det(s.p1 - s.p2)) < EPS

    def is_orthogonal_to(self, s):
        """
        直行しているかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Segment s:
        :return:
        """
        
        return abs((self.p1 - self.p2).dot(s.p1 - s.p2)) < EPS

    def intersects_with(self, s, allow_side=True):
        """
        交差するかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B&lang=ja
        :param Segment s:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        """
        if self.is_parallel_to(s):
            
            return (s.p1.on_segment(self.p1, self.p2, allow_side) or
                    s.p2.on_segment(self.p1, self.p2, allow_side) or
                    self.p1.on_segment(s.p1, s.p2, allow_side) or
                    self.p2.on_segment(s.p1, s.p2, allow_side))
        else:
            
            det_upper = EPS if allow_side else -EPS
            ok = True
            
            ok &= (self.p2 - self.p1).det(s.p1 - self.p1) * (self.p2 - self.p1).det(s.p2 - self.p1) < det_upper
            
            ok &= (s.p2 - s.p1).det(self.p1 - s.p1) * (s.p2 - s.p1).det(self.p2 - s.p1) < det_upper
            return ok

    def closest_point(self, p):
        """
        線分上の、p に最も近い点
        :param Point p:
        """
        
        d = (p - self.p1).dot(self.p2 - self.p1) / self.norm()
        
        if d < EPS:
            return self.p1
        
        if -EPS < d - self.norm():
            return self.p2
        
        return Point.from_polar(d, (self.p2 - self.p1).phase()) + self.p1

    def dist(self, p):
        """
        他の点との最短距離
        :param Point p:
        """
        return abs(p - self.closest_point(p))

    def dist_segment(self, s):
        """
        他の線分との最短距離
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D&lang=ja
        :param Segment s:
        """
        if self.intersects_with(s):
            return 0.0
        return min(
            self.dist(s.p1),
            self.dist(s.p2),
            s.dist(self.p1),
            s.dist(self.p2),
        )

    def has_point(self, p, allow_side=True):
        """
        p が線分上に乗っているかどうか
        :param Point p:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        """
        return p.on_segment(self.p1, self.p2, allow_side=allow_side)


class Polygon:
    """
    2次元空間上の多角形
    """

    def __init__(self, points):
        """
        :param list of Point points:
        """
        self.points = points

    def iter2(self):
        """
        隣り合う2点を順に返すイテレータ
        :rtype: typing.Iterator[(Point, Point)]
        """
        return zip(self.points, self.points[1:] + self.points[:1])

    def iter3(self):
        """
        隣り合う3点を順に返すイテレータ
        :rtype: typing.Iterator[(Point, Point, Point)]
        """
        return zip(self.points,
                   self.points[1:] + self.points[:1],
                   self.points[2:] + self.points[:2])

    def area(self):
        """
        面積
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A&lang=ja
        """
        
        dets = []
        for p, q in self.iter2():
            dets.append(p.det(q))
        return abs(math.fsum(dets)) / 2

    def is_convex(self, allow_straight=False, allow_collapsed=False):
        """
        凸多角形かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B&lang=ja
        :param allow_straight: 3点がまっすぐ並んでるのを許容するかどうか
        :param allow_collapsed: 面積がゼロの場合を許容するか
        """
        ccw = []
        for a, b, c in self.iter3():
            ccw.append(Point.ccw(a, b, c))
        ccw = set(ccw)
        if len(ccw) == 1:
            if ccw == {Point.CCW_CLOCKWISE}:
                return True
            if ccw == {Point.CCW_COUNTER_CLOCKWISE}:
                return True
        if allow_straight and len(ccw) == 2:
            if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_CLOCKWISE}:
                return True
            if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_COUNTER_CLOCKWISE}:
                return True
        if allow_collapsed and len(ccw) == 3:
            return ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_ONLINE_BACK, Point.CCW_ON_SEGMENT}
        return False

    def has_point_on_edge(self, p):
        """
        指定した点が辺上にあるか
        :param Point p:
        :rtype: bool
        """
        for a, b in self.iter2():
            if p.on_segment(a, b):
                return True
        return False

    def contains(self, p, allow_on_edge=True):
        """
        指定した点を含むか
        Winding Number Algorithm
        https://www.nttpc.co.jp/technology/number_algorithm.html
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C&lang=ja
        :param Point p:
        :param bool allow_on_edge: 辺上の点を許容するか
        """
        angles = []
        for a, b in self.iter2():
            if p.on_segment(a, b):
                return allow_on_edge
            angles.append(p.angle(a, b))
        
        return abs(math.fsum(angles)) > EPS

    @staticmethod
    def convex_hull(points, allow_straight=False):
        """
        凸包。x が最も小さい点のうち y が最も小さい点から反時計回り。
        Graham Scan O(N log N)
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A&lang=ja
        :param list of Point points:
        :param allow_straight: 3点がまっすぐ並んでるのを許容するかどうか
        :rtype: list of Point
        """
        points = points[:]
        points.sort(key=lambda p: (p.x, p.y))

        
        det_lower = -EPS if allow_straight else EPS

        sz = 0
        
        ret = [None] * (len(points) * 2)
        for p in points:
            while sz > 1 and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
                sz -= 1
            ret[sz] = p
            sz += 1
        floor = sz
        for p in reversed(points[:-1]):
            while sz > floor and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
                sz -= 1
            ret[sz] = p
            sz += 1
        ret = ret[:sz - 1]

        if allow_straight and len(ret) > len(points):
            
            ret = points
        return ret

    @staticmethod
    def diameter(points):
        """
        直径
        凸包構築 O(N log N) + カリパー法 O(N)
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B&lang=ja
        :param list of Point points:
        """
        
        points = Polygon.convex_hull(points, allow_straight=False)
        if len(points) == 1:
            return 0.0
        if len(points) == 2:
            return abs(points[0] - points[1])

        
        si = points.index(min(points, key=lambda p: (p.x, p.y)))
        sj = points.index(max(points, key=lambda p: (p.x, p.y)))
        n = len(points)

        ret = 0.0
        
        i, j = si, sj
        while i != sj or j != si:
            ret = max(ret, abs(points[i] - points[j]))
            ni = (i + 1) % n
            nj = (j + 1) % n
            
            if (points[ni] - points[i]).det(points[nj] - points[j]) > 0:
                j = nj
            else:
                i = ni
        return ret

    def convex_cut_by_line(self, line_p1, line_p2):
        """
        凸多角形を直線 line_p1-line_p2 でカットする。
        凸じゃないといけません
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C&lang=ja
        :param line_p1:
        :param line_p2:
        :return: (line_p1-line_p2 の左側の多角形, line_p1-line_p2 の右側の多角形)
        :rtype: (Polygon|None, Polygon|None)
        """
        n = len(self.points)
        line = Line.from_segment(line_p1, line_p2)
        
        on_line_points = []
        for i, p in enumerate(self.points):
            if line.has_point(p):
                on_line_points.append(i)

        
        has_on_line_edge = False
        if len(on_line_points) >= 3:
            has_on_line_edge = True
        elif len(on_line_points) == 2:
            
            has_on_line_edge = abs(on_line_points[0] - on_line_points[1]) in [1, n - 1]
        
        if has_on_line_edge:
            for p in self.points:
                ccw = Point.ccw(line_p1, line_p2, p)
                if ccw == Point.CCW_COUNTER_CLOCKWISE:
                    return Polygon(self.points[:]), None
                if ccw == Point.CCW_CLOCKWISE:
                    return None, Polygon(self.points[:])

        ret_lefts = []
        ret_rights = []
        d = line_p2 - line_p1
        for p, q in self.iter2():
            det_p = d.det(p - line_p1)
            det_q = d.det(q - line_p1)
            if det_p > -EPS:
                ret_lefts.append(p)
            if det_p < EPS:
                ret_rights.append(p)
            
            if det_p * det_q < -EPS:
                intersection = line.intersection_point(Line.from_segment(p, q))
                ret_lefts.append(intersection)
                ret_rights.append(intersection)

        
        l = Polygon(ret_lefts) if len(ret_lefts) > 1 else None
        r = Polygon(ret_rights) if len(ret_rights) > 1 else None
        return l, r


class Circle:
    def __init__(self, o, r):
        """
        :param Point o:
        :param float r:
        """
        self.o = o
        self.r = r

    def __eq__(self, other):
        return self.o == other.o and abs(self.r - other.r) < EPS

    def ctc(self, c):
        """
        共通接線 common tangent の数
        4: 離れてる
        3: 外接
        2: 交わってる
        1: 内接
        0: 内包
        inf: 同一
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=ja
        :param Circle c:
        :rtype: int
        """
        if self.o == c.o:
            return INF if abs(self.r - c.r) < EPS else 0
        
        d = self.o.dist(c.o) - self.r - c.r
        if d > EPS:
            return 4
        elif d > -EPS:
            return 3
        
        elif d + min(self.r, c.r) * 2 > EPS:
            return 2
        elif d + min(self.r, c.r) * 2 > -EPS:
            return 1
        return 0

    def has_point_on_edge(self, p):
        """
        指定した点が円周上にあるか
        :param Point p:
        :rtype: bool
        """
        return abs(self.o.dist(p) - self.r) < EPS

    def contains(self, p, allow_on_edge=True):
        """
        指定した点を含むか
        :param Point p:
        :param bool allow_on_edge: 辺上の点を許容するか
        """
        if allow_on_edge:
            
            return self.o.dist(p) - self.r < EPS
        else:
            
            return self.o.dist(p) - self.r < -EPS

    def area(self):
        """
        面積
        """
        return self.r ** 2 * PI

    def circular_segment_area(self, angle):
        """
        弓形⌓の面積
        :param float angle: 角度ラジアン
        """
        
        sector_area = self.area() * angle / TAU
        
        return sector_area - self.r ** 2 * math.sin(angle) / 2

    def intersection_points(self, other, allow_outer=False):
        """
        :param Segment|Circle other:
        :param bool allow_outer:
        """
        if isinstance(other, Segment):
            return self.intersection_points_with_segment(other, allow_outer=allow_outer)
        if isinstance(other, Circle):
            return self.intersection_points_with_circle(other)
        raise NotImplementedError()

    def intersection_points_with_segment(self, s, allow_outer=False):
        """
        線分と交差する点のリスト
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D&lang=ja
        :param Segment s:
        :param bool allow_outer: 線分の間にない点を含む
        :rtype: list of Point
        """
        
        projection_point = self.o.projection_point(s.p1, s.p2, allow_outer=True)
        
        dist = self.o.dist(projection_point)
        
        if dist - self.r > EPS:
            return []
        if dist - self.r > -EPS:
            if allow_outer or s.has_point(projection_point):
                return [projection_point]
            else:
                return []
        
        diff = Point.from_polar(math.sqrt(self.r ** 2 - dist ** 2), s.phase())
        ret1 = projection_point + diff
        ret2 = projection_point - diff
        ret = []
        if allow_outer or s.has_point(ret1):
            ret.append(ret1)
        if allow_outer or s.has_point(ret2):
            ret.append(ret2)
        return ret

    def intersection_points_with_circle(self, other):
        """
        円と交差する点のリスト
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E&langja
        :param circle other:
        :rtype: list of Point
        """
        ctc = self.ctc(other)
        if not 1 <= ctc <= 3:
            return []
        if ctc == 3:
            
            return [Point.from_polar(self.r, (other.o - self.o).phase()) + self.o]
        if ctc == 1:
            
            if self.r > other.r:
                return [Point.from_polar(self.r, (other.o - self.o).phase()) + self.o]
            else:
                return [Point.from_polar(self.r, (self.o - other.o).phase()) + self.o]
        
        assert ctc == 2

        a = other.r
        b = self.r
        c = self.o.dist(other.o)
        
        cos_a = (b ** 2 + c ** 2 - a ** 2) / (2 * b * c)
        angle = math.acos(cos_a)
        phi = (other.o - self.o).phase()
        return [
            self.o + Point.from_polar(self.r, phi + angle),
            self.o + Point.from_polar(self.r, phi - angle),
        ]

    def tangent_points_with_point(self, p):
        """
        p を通る接線との接点
        :param Point p:
        :rtype: list of Point
        """
        dist = self.o.dist(p)
        
        if dist - self.r < -EPS:
            
            return []
        if dist - self.r < EPS:
            
            return [Point(p.x, p.y)]

        a = math.sqrt(dist ** 2 - self.r ** 2)
        b = self.r
        c = dist
        
        cos_a = (b ** 2 + c ** 2 - a ** 2) / (2 * b * c)
        angle = math.acos(cos_a)
        phi = (p - self.o).phase()
        return [
            self.o + Point.from_polar(self.r, phi + angle),
            self.o + Point.from_polar(self.r, phi - angle),
        ]

    def tangent_points_with_circle(self, other):
        """
        other との共通接線との接点
        :param Circle other:
        :rtype: list of Point
        """
        ctc = self.ctc(other)
        if ctc > 4:
            raise ValueError('2つの円が同一です')
        if ctc == 0:
            return []
        if ctc == 1:
            return self.intersection_points_with_circle(other)

        assert ctc in (2, 3, 4)
        ret = []
        
        
        if abs(self.r - other.r) < EPS:
            
            phi = (other.o - self.o).phase()
            ret.append(self.o + Point.from_polar(self.r, phi + PI / 2))
            ret.append(self.o + Point.from_polar(self.r, phi - PI / 2))
        else:
            
            intersection = self.o + (other.o - self.o) / (self.r - other.r) * self.r
            ret += self.tangent_points_with_point(intersection)

        
        
        intersection = self.o + (other.o - self.o) / (self.r + other.r) * self.r
        ret += self.tangent_points_with_point(intersection)
        return ret

    @staticmethod
    def circumscribed_of(p1, p2, p3):
        """
        p1・p2・p3 のなす三角形の外接円
        Verify:
        :param Point p1:
        :param Point p2:
        :param Point p3:
        """
        if p1.on_segment(p2, p3):
            return Circle((p2 + p3) / 2, p2.dist(p3) / 2)
        if p2.on_segment(p1, p3):
            return Circle((p1 + p3) / 2, p1.dist(p3) / 2)
        if p3.on_segment(p1, p2):
            return Circle((p1 + p2) / 2, p1.dist(p2) / 2)
        o = Point.circumstance_of(p1, p2, p3)
        return Circle(o, o.dist(p1))

    @staticmethod
    def min_enclosing_circle(points):
        """
        points をすべて含む最小の円
        計算量の期待値は O(N)
        https://www.jaist.ac.jp/~uehara/course/2014/i481f/pdf/ppt-7.pdf
        Verify: https://atcoder.jp/contests/abc151/tasks/abc151_f
        :param list of Point points:
        :rtype: Circle
        """
        points = points[:]
        random.shuffle(points)

        
        ret = Circle(points[0], 0)
        for i, p in enumerate(points):
            if ret.contains(p):
                continue
            ret = Circle(p, 0)
            for j, q in enumerate(points[:i]):
                if ret.contains(q):
                    continue
                
                ret = Circle((p + q) / 2, abs(p - q) / 2)
                for k, r in enumerate(points[:j]):
                    if ret.contains(r):
                        continue
                    
                    ret = Circle.circumscribed_of(p, q, r)
        return ret


N = int(sys.stdin.buffer.readline())
XY = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(N)]

points = []
for x, y in XY:
    points.append(Point(x, y))
ans = Circle.min_enclosing_circle(points)
print(ans.r)

Solution (Python):

import math





def exist_same_point(a,b,c,d,e,f):
    
    return (a,b)==(c,d) or (c,d)==(e,f) or (e,f)==(a,b)




def three_points_on_a_line(a,b,c,d,e,f):

    dx1 = a-c
    dy1 = b-d
    dx2 = a-e
    dy2 = b-f

    return dx2*dy1 == dx1*dy2





def circumcenter(a,b,c,d,e,f):

    if exist_same_point(a,b,c,d,e,f) or three_points_on_a_line(a,b,c,d,e,f):
        return None,None,None

    aa = a * a
    bb = b * b
    cc = c * c
    dd = d * d
    ee = e * e
    ff = f * f

    py = ((e - a) * (aa + bb - cc - dd) - (c - a) * (aa + bb - ee- ff)) / (2 * (e - a)*(b - d) - 2 * (c - a) * (b - f))

    px = (2 * (b - f) * py - aa - bb + ee + ff) / (2 * (e - a)) \
        if (c == a) else (2 * (b - d) * py - aa - bb + cc + dd) / (2 * (c - a))

    r = math.hypot(px - a, py - b)

    return px,py,r


def in_c(x,y,r):

    for i in range(N):

        if math.hypot(x-xy[i][0],y-xy[i][1]) > r+10**(-6):
            return False

    return True


N = int(input())

xy = []
ans = float("inf")

for i in range(N):
    x,y = map(int,input().split())
    xy.append([x,y])

for i in range(N):
    for j in range(i):

        nx = (xy[i][0] + xy[j][0]) / 2
        ny = (xy[i][1] + xy[j][1]) / 2
        nr = math.hypot(xy[i][0] - xy[j][0],xy[i][1] - xy[j][1]) / 2

        if in_c(nx,ny,nr):
            ans = min(ans,nr)

for i in range(N):
    for j in range(i):
        for k in range(j):

            nx,ny,nr = circumcenter(xy[i][0],xy[i][1],xy[j][0],xy[j][1],xy[k][0],xy[k][1])
            if nx != None and in_c(nx,ny,nr):
                ans = min(ans,nr)

print (ans)