最小生成树,Kruskal算法。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 5052;
int n, p[MAXN], r[MAXN], u[MAXN], v[MAXN];
double dis[MAXN], x[102], y[102], ans;
int cmp(const int i, const int j)
{
return dis[i] < dis[j] ? 1 : 0;
}
int find(int i)
{
return p[i] == i ? i : p[i] = find(p[i]);
}
void Kruskal()
{
ans = 0;
for(int i=0; i<n; i++)
p[i] = i;
sort(r, r+n, cmp);
for(int i=0; i<n; i++)
{
int e = r[i];
int xx = find(u[e]);
int yy = find(v[e]);
if(xx != yy)
{
ans += dis[e];
p[xx] = yy;
}
}
}
int main()
{
#ifdef test
freopen("sample.txt", "r", stdin);
#endif
int t, num;
scanf("%d", &t);
while(t--)
{
n = 0;
double d1, d2;
scanf("%d", &num);
for(int i=0; i<num; i++)
scanf("%lf%lf", &x[i], &y[i]);
for(int i=0; i<num; i++)
for(int j=i+1; j<num; j++)
{
u[n] = i;
v[n] = j;
r[n] = n;
d1 = double(x[i] - x[j]);
d2 = double(y[i] - y[j]);
dis[n++] = sqrt(d1*d1+d2*d2);
}
Kruskal();
printf("%.2lf\n", ans);
if(t)
puts("");
}
return 0;
}