题意:
有许多基地,每个基地都有两种收发信号的方式,一种是通过无线电收发机,另一种是通过卫星。两个基地之间可以通过卫星交流不管它们相距多远;但是通过无线电交流,就要求它们的距离不超过D。为了方便布置,节省成本,每个基地的无线电交流的最大距离都相等。给出基地的位置和卫星的数量,求出D,保证两个基地之间至少一个交流路径。
思路:
求出MST,保证了两点之间有路径,然后按照从大到小的顺序给在生成树中的边排序,将卫星安排给权值大的边,保证D尽可能小。s个卫星可以安排给s-1条边(s个点),所以第s条边的权值就是所求。克鲁斯卡尔算法,复杂度mlog(m)。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <vector> 5 #include <math.h> 6 using namespace std; 7 8 const int N = 505; 9 10 struct edge 11 { 12 int x,y; 13 double cost; 14 15 edge(int a,int b,double c) 16 { 17 x = a; 18 y = b; 19 cost = c; 20 } 21 }; 22 23 int px[N],py[N]; 24 int par[N]; 25 26 vector<edge> es; 27 vector<double> vd; 28 29 double cal(int i,int j) 30 { 31 double x2 = (px[i] - px[j]) * (px[i] - px[j]); 32 double y2 = (py[i] - py[j]) * (py[i] - py[j]); 33 34 return sqrt(x2 + y2); 35 } 36 37 bool cmp(edge a,edge b) 38 { 39 return a.cost < b.cost; 40 } 41 42 int fin(int x) 43 { 44 if (x == par[x]) return x; 45 else return par[x] = fin(par[x]); 46 } 47 48 void unit(int x,int y) 49 { 50 x = fin(x); 51 y = fin(y); 52 53 if (x == y) return; 54 55 par[x] = y; 56 } 57 58 bool comp(double a,double b) 59 { 60 return a > b; 61 } 62 63 int main() 64 { 65 int t; 66 67 scanf("%d",&t); 68 69 while (t--) 70 { 71 int s,n; 72 73 es.clear(); 74 75 vd.clear(); 76 77 scanf("%d%d",&s,&n); 78 79 for (int i = 0;i <= n;i++) par[i] = i; 80 81 for (int i = 0;i < n;i++) 82 { 83 scanf("%d%d",&px[i],&py[i]); 84 } 85 86 for (int i = 0;i < n;i++) 87 { 88 for (int j = i + 1;j < n;j++) 89 { 90 double len = cal(i,j); 91 92 es.push_back(edge(i,j,len)); 93 } 94 } 95 96 sort(es.begin(),es.end(),cmp); 97 98 for (int i = 0;i < es.size();i++) 99 { 100 int x = es[i].x,y = es[i].y; 101 102 if (fin(x) == fin(y)) continue; 103 104 unit(x,y); 105 106 vd.push_back(es[i].cost); 107 } 108 109 sort(vd.begin(),vd.end(),comp); 110 111 double ans = 0; 112 113 printf("%.2f ",vd[s-1]); 114 } 115 116 return 0; 117 }