luoguP1991无线通讯网
国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络。每个边防哨所都要配置无线电收发器;有一些哨所还可以配备卫星电话
任意两个配置了一条卫星电话线路的哨所(两边均有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率的限制。
收发器的功率越高,通话距离D会更远,但价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。
你的任务是确定收发器必须的最小通话距离,使得每一对哨所之间至少有一条通话路径(直接或间接)
输入格式:
从 wireless.in 中输入数据第 1 行,2 个整数 S 和 P,S 表示可安装的卫星电话的哨所
数,P 表示边防哨所的数量。接下里 P 行,每行两个整数 x,y 描述一个哨所的平面坐标
(x, y),以 km 为单位。
输出 wireless.out 中
第 1 行,1 个实数 D,表示无线电收发器的最小传输距离,精确到小数点后两位。
输入样例#1:
2 4
0 100
0 300
0 600
150 750
输出样例#1:
212.13
问题解决的巨大关键是什么是最小传输距离
我们仔细读题+思考后,可以发现这题的题面扯了一堆废话使这道题变的好像nb了。其实很简单。
首先我们用一下贪心的思想,对于S个卫星电话,我们肯定是要给最长的S条边用
这样我们把所有点排个序
然后我们再想想,要知道两个哨所之间是否有通话路径,也就是我们要判断连通性,同时结合我们要排序,加之数据范围小
我们就得到结论:用并查集处理连通性问题,
总之排序+并查集,就是kruskal了,当时这是kruskal的变形,本题并不是标准的最小生成树,但是用的是最小生成树的做法a
因为我们最终要使每一对哨所之间至少有一条通话路径,而且后S个哨所是确定要使用卫星电话的
所以我们处理到p-s就行了
也就是我们只需要处理前p-s条边即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 510; 4 struct enkidu { 5 int x1, x2; 6 double val; 7 }e[maxn * maxn]; 8 struct enuma { 9 int x, y; 10 }a[maxn]; 11 int s, p; 12 int len = 0; 13 int fa[maxn]; 14 15 inline int read() { 16 int x = 0, y = 1; 17 char ch = getchar(); 18 while(!isdigit(ch)) { 19 if(ch == '-') y = -1; 20 ch = getchar(); 21 } 22 while(isdigit(ch)) { 23 x = (x << 1) + (x << 3) + ch - '0'; 24 ch = getchar(); 25 } 26 return x * y; 27 } 28 29 inline bool cmp(enkidu a, enkidu b) { 30 return a.val < b.val;} 31 32 inline double dist(int p, int q) { 33 return sqrt(pow(double(a[p].x - a[q].x), 2) + pow(double(a[p].y - a[q].y), 2)); 34 } 35 36 int getfather(int x) { 37 if(fa[x] == x) return x; 38 return fa[x] = getfather(fa[x]); 39 } 40 41 int main() { 42 s = read(), p = read(); 43 for(int i = 1; i <= p; ++i) { 44 a[i].x = read(), a[i].y = read(); 45 fa[i] = i; 46 } 47 for(int i = 1; i <= p; ++i) 48 for(int j = i + 1; j <= p; ++j) { 49 e[++len].x1 = i; 50 e[len].x2 = j; 51 e[len].val = dist(i, j); 52 //cout << e[len].val; 53 } 54 sort(e + 1, e + len + 1, cmp); 55 double ans = 0; 56 int num = p - s; 57 for(int i = 1; i <= len, num > 0; ++i) { 58 int u = getfather(e[i].x1); 59 int v = getfather(e[i].x2); 60 if(u != v) { 61 num--; 62 ans = max(ans, e[i].val); 63 fa[u] = v; 64 } 65 } 66 cout << setiosflags(ios::fixed) << setprecision(2); 67 cout << ans << '\n'; 68 return 0; 69 }