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 }

 

posted @ 2018-08-05 20:43  YuWenjue  阅读(133)  评论(0编辑  收藏  举报