给出n个点的坐标和s个卫星 求最小生成树 因为每2个卫星之间可以直接通讯,所以可以删除s-1条边,然后输出删除s-1条边之后剩余的边中最长的边 #include <iostream> #include <cmath> #include <algorithm> #include <vector> using namespace std; const int N=505; class node //存储所有的边 { public: int u,v; double w; }; class point //存储所有点的坐标,用于构图 { public: double x,y; }; point map[N]; node edge[N*N]; int par[N],n,s,sizeEdge; double sum; vector<node> vec; //存储生成树中所有的边 int cmp(const node &a,const node &b) { return a.w<b.w; } void makeSet() { for(int i=0;i<=n;++i) par[i]=i; } int findSet(const int &x) { if(par[x]!=x) par[x]=findSet(par[x]); return par[x]; } inline void unionSet(const int &r1,const int &r2) { par[r1]=r2; } void kruskal() { int ans=0,root1,root2; makeSet(); for(int i=0;i<sizeEdge;++i) { root1=findSet(edge[i].u); root2=findSet(edge[i].v); if(root1 != root2) { ans++; unionSet(root1,root2); vec.push_back(edge[i]); sum+=edge[i].w; if(ans==n-1) return ; } } } void createG() //构图 { double dx,dy; sizeEdge=0; for(int i=0;i<n;++i) //求出某点到其余点的距离 for(int j=0;j<n;++j) { if(i==j) continue; edge[sizeEdge].u=i+1; edge[sizeEdge].v=j+1; dy=map[j].y-map[i].y; dx=map[j].x-map[i].x; edge[sizeEdge++].w=sqrt( dy*dy + dx*dx ); } sort(edge,edge+sizeEdge,cmp); } int main() { int cas; cin>>cas; while(cas--) { sum=0; vec.clear(); cin>>s>>n; s-=1; for(int i=0;i<n;++i) cin>>map[i].x>>map[i].y; createG(); kruskal(); sort(vec.begin(),vec.end(),cmp); //将结果中的边排序,输出删除s-1条边之后最大的边 printf("%.2lf/n",vec[vec.size()-1-s].w); } system("pause"); return 0; }