http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1914
解题思路:最小生成树,从最小边开始加入,这样第m - n 条边的权值就是答案
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <queue>
#include <stack>
#include <vector>
#include <map>
using namespace std;
#define N 1006
#define INF 0xfffffff
#define PI acos (-1.0)
#define EPS 1e-8
struct node
{
double x, y, d;
} stu[N*N], p[N*N];
bool cmp (node a, node b)
{
return (a.d < b.d);
}
int n, m, k, f[N];
int Find (int x)
{
if (x != f[x])
f[x] = Find (f[x]);
return f[x];
}
void kruskal ();
int main ()
{
int t;
scanf ("%d", &t);
while (t--)
{
scanf ("%d %d", &n, &m);
for (int i=1; i<=m; i++)
f[i] = i;
for (int i=1; i<=m; i++)
scanf ("%lf %lf", &stu[i].x, &stu[i].y);
k = 0;
for (int i=1; i<m; i++)
{
for (int j=i+1; j<=m; j++)
{
double d = sqrt ((stu[i].x*1.0-stu[j].x) * (stu[i].x*1.0-stu[j].x) + (stu[i].y*1.0-stu[j].y) * (stu[i].y*1.0-stu[j].y));
p[k].x = i, p[k].y = j, p[k++].d = d;
}
}
sort (p, p+k, cmp);
kruskal ();
}
return 0;
}
void kruskal ()
{
int flag = 0;
double ans = 0;
for (int i=0; i<k; i++)
{
int xx = Find (p[i].x), yy = Find (p[i].y);
if (xx != yy)
{
f[xx] = yy;
flag++;
if (flag == m-n)
{
ans = p[i].d;
break;
}
}
}
printf ("%.2f\n", ans);
}