#include <bits/stdc++.h>
using namespace std;
#define int double
#define endl "\n"
struct Edge {
int u, v;
double weight;
bool operator<(const Edge &other) const {
return weight < other.weight;
}
};
double dis(pair<double,double> a, pair<double,double> b){
return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2));
}
int find(int x, vector<int> par){
if(par[x] == x)return x;
return find(par[x], par);
}
bool join(int x, int y, vector<int> &par){
int u = find(x, par), v = find(y, par);
if(u == v)return false;
par[v] = u;
return true;
}
double kruska(int n, vector<pair<double,double>> &points){
vector<Edge> edges;
vector<int> par(n + 1);
for(int i = 0; i < n; i++){
par[i] = i;
for(int j = i + 1; j < n; j++){
edges.push_back({i,j,dis(points[i], points[j])});
}
}
sort(edges.begin(), edges.end());
int cnt = 0;
double sum = 0.00;
for(int i = 0; i < edges.size(); i++){
if(join(edges[i].u, edges[i].v,par)){
sum += edges[i].weight;
cnt++;
if(cnt == n - 1)break;
}
}
return sum;
}
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int tc;cin >> tc;
// string s; getline(cin, s);
while(tc--){
int n; cin >> n;
vector<pair<double,double>> points(n);
for(int i = 0; i < n; i++){
cin >> points[i].first >> points[i].second;
}
double result = kruska(n ,points);
cout << fixed << setprecision(2) << result << endl;
if(tc>0)cout << endl;
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwojZGVmaW5lIGludCBkb3VibGUKI2RlZmluZSBlbmRsICJcbiIKCnN0cnVjdCBFZGdlIHsKICAgIGludCB1LCB2OwogICAgZG91YmxlIHdlaWdodDsKICAgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IEVkZ2UgJm90aGVyKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHdlaWdodCA8IG90aGVyLndlaWdodDsKICAgIH0KfTsKCmRvdWJsZSBkaXMocGFpcjxkb3VibGUsZG91YmxlPiBhLCBwYWlyPGRvdWJsZSxkb3VibGU+IGIpewoJcmV0dXJuIHNxcnQocG93KGEuZmlyc3QgLSBiLmZpcnN0LCAyKSArIHBvdyhhLnNlY29uZCAtIGIuc2Vjb25kLCAyKSk7Cn0KCmludCBmaW5kKGludCB4LCB2ZWN0b3I8aW50PiBwYXIpewoJaWYocGFyW3hdID09IHgpcmV0dXJuIHg7CglyZXR1cm4gZmluZChwYXJbeF0sIHBhcik7Cn0KCmJvb2wgam9pbihpbnQgeCwgaW50IHksIHZlY3RvcjxpbnQ+ICZwYXIpewoJaW50IHUgPSBmaW5kKHgsIHBhciksIHYgPSBmaW5kKHksIHBhcik7CglpZih1ID09IHYpcmV0dXJuIGZhbHNlOwoJcGFyW3ZdID0gdTsKCXJldHVybiB0cnVlOwp9Cgpkb3VibGUga3J1c2thKGludCBuLCB2ZWN0b3I8cGFpcjxkb3VibGUsZG91YmxlPj4gJnBvaW50cyl7Cgl2ZWN0b3I8RWRnZT4gZWRnZXM7Cgl2ZWN0b3I8aW50PiBwYXIobiArIDEpOwoJCglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKCQlwYXJbaV0gPSBpOwoJCWZvcihpbnQgaiA9IGkgKyAxOyBqIDwgbjsgaisrKXsKCQkJZWRnZXMucHVzaF9iYWNrKHtpLGosZGlzKHBvaW50c1tpXSwgcG9pbnRzW2pdKX0pOwoJCX0KCX0KCQoJc29ydChlZGdlcy5iZWdpbigpLCBlZGdlcy5lbmQoKSk7CgkKCWludCBjbnQgPSAwOwoJZG91YmxlIHN1bSA9IDAuMDA7CgkKCWZvcihpbnQgaSA9IDA7IGkgPCBlZGdlcy5zaXplKCk7IGkrKyl7CgkJaWYoam9pbihlZGdlc1tpXS51LCBlZGdlc1tpXS52LHBhcikpewoJCQlzdW0gKz0gZWRnZXNbaV0ud2VpZ2h0OwoJCQljbnQrKzsKCQkJaWYoY250ID09IG4gLSAxKWJyZWFrOwoJCX0KCX0KCXJldHVybiBzdW07Cn0KCnNpZ25lZCBtYWluKCl7Cglpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKDApOwogICAgY2luLnRpZSgwKTtjb3V0LnRpZSgwKTsKICAgIGludCB0YztjaW4gPj4gdGM7Ci8vICAgIHN0cmluZyBzOyBnZXRsaW5lKGNpbiwgcyk7CiAgICB3aGlsZSh0Yy0tKXsKICAgIAlpbnQgbjsgY2luID4+IG47CiAgICAJdmVjdG9yPHBhaXI8ZG91YmxlLGRvdWJsZT4+IHBvaW50cyhuKTsKCQkKCQlmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKCQkJY2luID4+IHBvaW50c1tpXS5maXJzdCA+PiBwb2ludHNbaV0uc2Vjb25kOwoJCX0gCgkJCgkJZG91YmxlIHJlc3VsdCA9IGtydXNrYShuICxwb2ludHMpOwoJCWNvdXQgPDwgZml4ZWQgPDwgc2V0cHJlY2lzaW9uKDIpIDw8IHJlc3VsdCA8PCBlbmRsOwoJCWlmKHRjPjApY291dCA8PCBlbmRsOwoJfQoJcmV0dXJuIDA7Cn0K