Problem: Example

Input

8 900 0
40 100
70 -80
350 30
680 -20
230 230
300 400
530 130
75 -275


Output

1210.99416

Solution (in CPP):

Solution:
#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))

using namespace std;

template<class T>void reg(vector<T> &ary,const T &elem){ary.emplace_back(elem);}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}
template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}

using R=long double;
const R EPS=1E-11,INF=1E40,PI = acos(R(-1));
inline int sgn(const R& r){ return (r > EPS) - (r < -EPS);}
inline R sq(R x){return sqrt(max<R>(x,0.0));}

using P=complex<R>;
using VP=vector<P>;
using L=struct{P s,t;};
using VL=vector<L>;

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))==0 && sgn(imag(a-b))==0;}
}

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

P proj(L l,P p){l.t-=l.s,p-=l.s;return l.s+l.t*real(p/l.t);}

R dsp(L s,P p){
	if(sgn(dot(s.s,s.t,p))<=0) return abs(p-s.s);
	if(sgn(dot(s.t,s.s,p))<=0) return abs(p-s.t);
	return abs(det(s.s,s.t,p))/abs(s.t-s.s);
}

using C=struct{P c;R r;};
using VC=vector<C>;

enum RCC{IN=1,ON_IN=2,ISC=4,ON_OUT=8,OUT=16,ONS=10};
int rcc(C a,C b){
	R d=abs(a.c-b.c);
	if(a.r+b.r<d) return OUT;
	if(a.r+b.r==d) return ON_OUT;
	if(abs(a.r-b.r)<d) return ISC;
	if(abs(a.r-b.r)==d) return ON_IN;
	return IN;
}

bool icp(C c,P p,int end=0){return sgn(norm(p-c.c)-norm(c.r))<=-end;}
bool ics(C c,L s,int end=0){return sgn(dsp(s,c.c)-c.r)<=-end;}

P cir(C c,R t){return c.c+polar(c.r,t);}

VP pcl(C c, L l) {
	P h=proj(l,c.c),e=(l.t-l.s)/abs(l.t-l.s)*sq(norm(c.r)-norm(h-c.c));
	return VP{h-e,h+e};
}

VP pcc(C a,C b){
	P d=b.c-a.c,w=(norm(d)+norm(a.r)-norm(b.r))/(2.0*norm(d))*d,h=a.c+w,e=w*P(0,1);
	return pcl(a,{h-e,h+e}); 
}

L tan(C c,R t){
	P p=cir(c,t),d=polar(c.r,t)*P(0,1);
	return L{p-d,p+d};
}

VL tan(C c,P p){
	VL res;R t=arg(p-c.c),d=acos(c.r/abs(p-c.c));
	reg(res,tan(c,t+d));
	if(sgn(d)) reg(res,tan(c,t-d));			
	return res;
}

VL tan(C a,C b){
	VL res;R t=arg(b.c-a.c),d=abs(b.c-a.c),i=acos((a.r+b.r)/d),o=acos((a.r-b.r)/d);
	int r=rcc(a,b);
	if(r==OUT) reg(res,tan(a,t+i)),reg(res,tan(a,t-i));
	if(r>=ISC) reg(res,tan(a,t+o)),reg(res,tan(a,t-o));
	if(r&ONS) reg(res,tan(a,t));
	return res;
}

const int vmax=5010;
struct node{int to;R cost;};
vector<node> graph[vmax];

inline void add_edge(int f,int t,R c){reg(graph[f],{t,c}),reg(graph[t],{f,c});}

void circle_arrangement(const VC &circle,VP &point){
	VP candiate;	
	auto can=[&](P p){for(auto &c:circle) if(icp(c,p,1)) return; reg(candiate,p);};
	auto check1=[&](P p){for(auto &c:circle) if(icp(c,p,1)) return false; return true;};
	auto check2=[&](L s){for(auto &c:circle) if(ics(c,s,1)) return false; return true;};
	
	for(auto &c1:circle){
		rep(j,4) can(cir(c1,j*PI/2.0));
		for(auto &p:point) for(auto &l:tan(c1,p)) can(proj(l,c1.c));
		for(auto &c2:circle){
			if(rcc(c1,c2)==ISC) for(auto &p:pcc(c1,c2)) can(p);
			for(auto &l:tan(c1,c2)) can(proj(l,c1.c)),can(proj(l,c2.c));
		}
	}	
	uniq(candiate),move(_all(candiate),back_inserter(point));
	for(auto &c:circle){
		vector<pair<R,int>> idx;
		rep(i,point.size()) if(sgn(norm(c.c-point[i])-norm(c.r))==0) reg(idx,{arg(point[i]-c.c),i});
		sort(_all(idx)),reg(idx,{idx[0].first+2*PI,idx[0].second});
		rep(i,1,idx.size()){
			R a1=idx[i-1].first,a2=idx[i].first;
			P mid=cir(c,(a1+a2)/2.0);
			if(check1(mid)) add_edge(idx[i-1].second,idx[i].second,c.r*(a2-a1));
		}
	}
	rep(i,point.size())rep(j,i){
		L l={point[i],point[j]};
		if(check2(l)) add_edge(i,j,abs(l.t-l.s));
	}
}

R dist[vmax];
void dijkstra(int s){
	fill(dist,dist+vmax,INF);
	using state=tuple<R,int>;
	priority_queue<state,vector<state>,greater<state>> q;
	dist[s]=0,q.push(state(0,s));
	while(!q.empty()){
		R c;int v;
		tie(c,v)=q.top();q.pop();
		for(auto &e:graph[v]){
			R nc=c+e.cost; int nv=e.to;
			if(chmin(dist[nv],nc)) q.push(state(nc,nv));
		}
	}
}

int main(void){
	int n;
	R x,y;
	cin >> n >> x >> y;
	P s=P(0,0),g=P(x,y);
	
	VC circle;
	rep(i,n) cin >> x >> y,reg(circle,{P(x,y),100.0});
	VP point={s,g};
	
	circle_arrangement(circle,point);
	dijkstra(0);
	
	cout.precision(20);
	R ans=(dist[1]>=INF?0.0:dist[1]);
	cout << fixed << ans << endl;
	return 0;
}