原题
北极的某区域共有n座村庄(1≤n≤500 ),每座村庄的坐标用一对整数(x,y)表示,其中 0≤x,y≤10000。为了加强联系,决定在村庄之间建立通讯网络。
通讯工具可以是无线电收发机,也可以是卫星设备。所有的村庄都可以拥有一部无线电收发机, 且所有的无线电收发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设备。
不同型号的无线电收发机有一个不同的参数d,两座村庄之间的距离如果不超过d就可以用该型号的无线电收发机直接通讯,d值越大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直接通讯。
现在有k台卫星设备,请你编写程序计算出如何分配可以使所拥有的无线电收发机的d值最小,并保证任意两个村庄都可以直接或间接通讯
输入
第一行输入包含N,即测试数据的数量。
每个测试用例的第一行包含1<=S<=100(卫星数),S<P<=500(前哨数)。
接下来P行,给出每个前哨(km,坐标是0到10,000之间的整数)的(x,y)坐标。
输出
每个样例输出一个最小d值,两位小数
样例输入
1 2 3 4 5 6
| 1 2 4 0 100 0 300 0 600 150 750
|
样例输出
提示
对于所有测试点,1<=N<=10。
题目大意
最小生成树,p个节点,s条路径,只能连p−s条线,输出最大的权值。
算法
最小生成树 kruskall算法
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<bits/stdc++.h> using namespace std; int a[1010]; int find(int x){ if(a[x]==x) return x; return a[x]=find(a[x]); } struct xy{ double x,y; }; struct node{ int a,b; double w; }; bool cmp(node a,node b){ return a.w<b.w; } inline double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int n; void kruskall(){ xy point[1010]; vector<node>v; int s,p,num=0; double d; cin>>s>>p; for(int i=1;i<=p;i++) a[i]=i; for(int i=1;i<=p;i++){ cin>>point[i].x>>point[i].y; } for(int i=1;i<=p;i++){ for(int j=1;j<=p;j++){ if(i!=j) v.push_back({i,j,dis(point[i].x,point[i].y,point[j].x,point[j].y)}); } } sort(v.begin(),v.end(),cmp); for(auto it:v){ int fa=find(it.a),fb=find(it.b); if(fa!=fb){ a[fa]=fb; num++; if(num==p-s){ d=it.w; break; } } } printf("%.2lf\n",d); } int main(){ cin>>n; while(n--) kruskall(); }
|
感谢观看qwq!