题意:给你S个卫星和P个哨兵,哨兵之间的沟通有两种方式,一种是通过卫星无论多大的距离都能,另一种是无线这种就要考虑距离,距离越大代价也就越大,但是哨兵必须要用一样的,让你求出用多大代价的无线设备才能使所有的哨兵之间有联系的代价最小,并输出那个代价最小要用的那个无线设备的代价。
思路:刚开始把这个题想的很复杂,后来一想就是先找一个最小生成树,完了再去掉最大S-1条线,剩下的最大的代价就是所求了。
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=510;
const int maxm=maxn*maxn/2;
int T,n,m,k;
double edge[maxn];
struct Node
{
int x;
int y;
} d[maxn];
struct node
{
int l;
int r;
double w;
} t[maxm];
int p[maxn];
int Find(int x)
{
if(p[x]==-1)
return x;
return p[x]=Find(p[x]);
}
int cmp(struct node a,struct node b)
{
return a.w<b.w;
}
double lpf()
{
int cnt=0;
for(int i=0; i<k; i++)
{
int a=Find(t[i].l);
int b=Find(t[i].r);
if(a!=b)
{
edge[cnt++]=t[i].w;
p[a]=b;
}
}
return edge[cnt-n]; //除去最大的S-1条边最大的边
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(p,-1,sizeof(p));
scanf("%d%d",&n,&m);
k=m*(m-1)/2;
for(int i=0; i<m; i++)
scanf("%d%d",&d[i].x,&d[i].y);
int cnt=0;
for(int i=0; i<m; i++)
{
for(int j=i+1; j<m; j++)
{
t[cnt].l=i;
t[cnt].r=j;
t[cnt++].w=sqrt((d[i].x-d[j].x)*(d[i].x-d[j].x)*1.0+(d[i].y-d[j].y)*(d[i].y-d[j].y)*1.0);
}
}
sort(t,t+cnt,cmp);
printf("%.2lf\n",lpf());
}
return 0;
}