Contents
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXN 10010
#define INF 0x3f3f3f3f
using namespace std;
int n, pp;
double ans;
int ranks[105], father[105];

struct node{ //存小岛的坐标
int x;
int y;
}node[105];

struct Edge{
int xx;
int yy;
double juli;
}edge[MAXN]; //边最多有n * (n - 1) / 2条

bool cmp(Edge e1, Edge e2){
return e1.juli < e2.juli ? 1 : -1; //注意这里是double的
}

void init_set()
{

for(int i = 0; i <= n; i++){
father[i] = i;
ranks[i] = 1;
}
}

int find_set(int x)
{

return x == father[x] ? father[x] : father[x] = find_set(father[x]);
}

void union_set(int x, int y)
{

if(ranks[x] >= ranks[y]){
ranks[x] += ranks[y];
father[y] = x;
}
else{
ranks[y] += ranks[x];
father[x] = y;
}
}

double distances(int x1, int y1, int x2, int y2)
{

double t = double((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
return sqrt(t);
}

double kruskal()
{

ans = 0.0;
//int N = n*(n - 1)/2;
sort(edge, edge + pp, cmp);
for(int i = 0; i < pp; i++){
int root_x = find_set(edge[i].xx);
int root_y = find_set(edge[i].yy);
if(root_x != root_y && edge[i].juli != INF){//如果未连通且距离不是无限远
ans += edge[i].juli;
union_set(root_x, root_y);
}
}
return ans;
}

int main()
{

freopen("input.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
init_set();
if(n == 1 || n == 0) {printf("oh!\n"); continue;}
for(int i = 0; i < n; i++){
scanf("%d%d", &node[i].x, &node[i].y);
}
double dis;
pp = 0;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
dis = distances(node[i].x, node[i].y, node[j].x, node[j].y);
if(dis < 10 || dis > 1000){
edge[i].xx = i;
edge[i].yy = j;
edge[i].juli = INF;
}
else{
edge[i].xx = i;
edge[i].yy = j;
edge[i].juli = dis;
}
pp++;
}
}
double cost = kruskal() * 100;
int flag = find_set(edge[2].xx);
if(ranks[flag] != n)
printf("oh!\n");
else{
printf("%.1f\n", cost);
}
}
return 0;
}
Contents