Arctic Network UVA - 10369 (最小生成树,适合prim)
给出n个点将他们连成最小生成树,给出k个卫星,有了这些卫星就可以无代价地连接一些边。求出在此条件下的最长的边
也就是求出最小生成树的第k小条边
考虑到这个图的边比较多,选择使用prim算法,需要注意的是,先生成的边不一定小,后生成的边也不一定大
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<climits>
#define int long long
#define endl '\n'
using namespace std;
const int inf=LLONG_MAX;
const int size=505;
int loop[size][size];
int vis[size];
int dis[size];
int locx[size];
int locy[size];
int date[size];
int n,k;
int cnt=0;
void prim(int beg)
{
int ind=beg;
memset(vis,0,sizeof(vis));
vis[ind]=1;
cnt=0;
for(int i=0;i<n;i++)
{
dis[i]=loop[i][ind];
}
for(int i=1;i<n;i++)
{
int rule=inf;
for(int j=0;j<n;j++)
{
if(!vis[j]&&dis[j]<rule)
{
rule=dis[j];
ind=j;
}
}
date[cnt++]=rule;
vis[ind]=1;
for(int j=0;j<n;j++)
{
if(!vis[j]&&loop[ind][j]<dis[j])
{
dis[j]=loop[ind][j];
}
}
}
}
void pre_solve()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
loop[i][j]=(locx[i]-locx[j])*(locx[i]-locx[j])+(locy[i]-locy[j])*(locy[i]-locy[j]);
}
}
}
int32_t main()
{
int t;
cin>>t;
while(t--)
{
scanf("%lld%lld",&k,&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&locx[i],&locy[i]);
}
pre_solve();
prim(0);
sort(date,date+cnt);
double ans=(double)date[n-k-1];
printf("%.2f\n",sqrt(ans));
}
return 0;
}