#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define REP(i,n) for(int (i) = 0;(i) < (n) ; ++(i)) #define REPS(a,i,n) for(int (i) = (a) ; (i) < (n) ; ++(i)) #if defined(_MSC_VER)||__cplusplus > 199711L #define AUTO(r,v) auto r = (v) #else #define AUTO(r,v) typeof(v) r = (v) #endif #define ALL(c) (c).begin() , (c).end() #define EACH(it,c) for(AUTO(it,(c).begin());it != (c).end();++it) #define LL long long #define int LL #define INF 999999999999 #define DEV 1000000007 #define QUICK_CIN ios::sync_with_stdio(false); cin.tie(0); using namespace std; class UnionFind{ public: //nは要素数 UnionFind(int n) : par(n), rank(n) { for (int i = 0; i < n; ++i){ par[i] = i; } } //xとyの属する集合を結合 void unite(int x, int y){ x = find(x); y = find(y); if (x == y)return; if (rank.at(x) < rank.at(y)){ par.at(x) = y; } else{ par.at(y) = x; if (rank.at(x) == rank.at(y))rank.at(x)++; } } bool same(int x, int y){ return find(x) == find(y); } private: //親 vector par; //根の深さ vector rank; //木の根を求める int find(int x){ if (par.at(x) == x){ return x; } else{ return par.at(x) = find(par.at(x)); } } }; double d[1002][1002]; complex p[1002]; int n; bool solve(double mu){ UnionFind uf(n); REP(i, n){ REP(j, n){ if (d[i][j] < mu){ uf.unite(i, j); } } } return uf.same(0,n-1); } signed main() { QUICK_CIN; //ifstream cin("debug.txt"); //ofstream cout("result.txt"); cin >> n; REP(i, n){ int x, y; cin >> x >> y; p[i] = { (double)x, (double)y }; } REP(i, n){ REP(j, n){ d[i][j] = norm(p[i] - p[j]); } } double left, midle, right; left = 0; right = 1e10; REP(i, 100){ midle = (left + right) / 2; if (!solve(midle*midle)){ left = midle; } else{ right = midle; } } int temp = midle+1; int ans = temp + 10 * (temp % 10 != 0) - temp % 10; cout << ans << endl; return 0; }