题意:也是求最小生成树,不过在n个点当中可以有s个点已经相连。
用krusical做。记录每次加的边数,当连通的边数有n-s便跳出。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,s,f[1010];
struct node
{
int x,y;
double s;
}e[250010];
bool cmp(node s, node v)
{
return s.s<v.s;
}
int find(int x)
{
if (x==f[x]) return x;
f[x]=find(f[x]);
return f[x];
}
void krusical(int p)
{
int i,t=0;
for (i=0; i<p; i++)
{
int x=find(e[i].x);
int y=find(e[i].y);
if (x!=y)
{
f[y]=f[x];
t++;
}
if (t==n-s) break;
}
printf("%.2f\n",e[i].s);
}
int main ()
{
int t,i,j;
cin>>t;
while(t--)
{
int zb[510][2],p=0;
cin>>s>>n;
for (i=1; i<=n; i++)
{
f[i]=i;
scanf("%d%d",&zb[i][0],&zb[i][1]);
}
for (i=1; i<n; i++)
for (j=i+1; j<=n; j++)
{
e[p].x=i;
e[p].y=j;
e[p].s=sqrt((zb[i][0]-zb[j][0])*(zb[i][0]-zb[j][0])+(zb[i][1]-zb[j][1])*(zb[i][1]-zb[j][1]));
p++;
}
sort(e,e+p,cmp);
krusical(p);
}
return 0;
}