居然是1A。和前面写过的一道修电脑的并查集的题目很像。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX = 205;
int fa[MAX], r[MAX];
struct EDGE
{
int from, to;
double cost;
EDGE(int a = 0, int b = 0, double c = 0.0)
: from(a), to(b), cost(c){}
}edge[MAX * MAX];
double x[MAX], y[MAX];
double dis(int a, int b)
{
return sqrt((x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b]));
}
int comp(EDGE a, EDGE b)
{
return a.cost < b.cost;
}
void init(int n)
{
for (int i = 1; i <= n; ++i)
{
fa[i] = i;
r[i] = 1;
}
}
int find(int x)
{
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void unite(int a, int b)
{
a = find(a);
b = find(b);
if (a == b)
return ;
if (r[a] < r[b])
fa[a] = b;
else
{
fa[b] = a;
if (r[a] == r[b])
r[a]++;
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int c;
scanf("%d", &c);
for (int i = 1; i <= c; ++i)
{
scanf("%lf%lf", &x[i], &y[i]);
}
int cnt = 0;
for (int i = 1; i <= c; ++i)
{
for (int j = 1; j <= c; ++j)
{
if (i != j)
{
++cnt;
edge[cnt] = EDGE(i, j, dis(i, j));
}
}
}
init(c);
double res = 0;
sort(edge + 1, edge + 1 + cnt, comp);
for (int i = 1; i <= cnt; ++i)
{
if (find(edge[i].to) != find(edge[i].from))
{
if (10 <= edge[i].cost && edge[i].cost <= 1000)
{
res += edge[i].cost * 100;
unite(edge[i].to, edge[i].from);
}
}
}
int judge = 0;
for (int i = 1; i <= c; ++i)
{
if (fa[i] == i)
judge++;
}
if (judge > 1)
printf("oh!\n");
else
printf("%.1f\n", res);
}
return 0;
}