[洛谷1991]无线通讯网
思路:
考虑使用卫星替代最小生成树中最大的$s-1$条边,答案即为剩下的最大边。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<algorithm> 6 inline int getint() { 7 char ch; 8 while(!isdigit(ch=getchar())); 9 int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return x; 12 } 13 inline int sqr(const int x) { 14 return x*x; 15 } 16 const int N=500; 17 struct Point { 18 int x,y; 19 friend double dist (const Point a,const Point b) { 20 return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); 21 } 22 }; 23 Point p[N]; 24 struct Edge { 25 int u,v; 26 double w; 27 bool operator < (const Edge &another) const { 28 return w<another.w; 29 } 30 }; 31 std::vector<Edge> e; 32 class DisjointSet { 33 private: 34 int anc[N]; 35 int Find(const int x) { 36 return x==anc[x]?x:anc[x]=Find(anc[x]); 37 } 38 public: 39 DisjointSet() { 40 for(int i=0;i<N;i++) anc[i]=i; 41 } 42 bool isConnected(const int x,const int y) { 43 return Find(x)==Find(y); 44 } 45 void Union(const int x,const int y) { 46 anc[Find(x)]=Find(y); 47 } 48 }; 49 DisjointSet s; 50 int main() { 51 int m=getint(),n=getint(); 52 for(int i=0;i<n;i++) { 53 p[i].x=getint(); 54 p[i].y=getint(); 55 } 56 for(int i=0;i<n;i++) { 57 for(int j=i+1;j<n;j++) { 58 e.push_back((Edge){i,j,dist(p[i],p[j])}); 59 } 60 } 61 std::sort(e.begin(),e.end()); 62 double ans; 63 for(unsigned i=0,cnt=n-m;i<e.size()&&cnt;i++) { 64 int u=e[i].u,v=e[i].v; 65 double w=e[i].w; 66 if(s.isConnected(u,v)) continue; 67 s.Union(u,v); 68 ans=w; 69 cnt--; 70 } 71 printf("%.2f",ans); 72 return 0; 73 }