P1991 无线通讯网

题目描述

国防部计划用无线网络连接若干个边防哨所。2 种不同的通讯技术用来搭建无线网络;

每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。

任意两个配备了一条卫星电话线路的哨所(两边都ᤕ有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过 D,这是受收发器的功率限制。收发器的功率越高,通话距离 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

说明

对于 20% 的数据:P = 2,S = 1

对于另外 20% 的数据:P = 4,S = 2

对于 100% 的数据保证:1 ≤ S ≤ 100,S < P ≤ 500,0 ≤ x,y ≤ 10000。

 

解析:

根据题意可知,卫星电话是随意分配的,不需要花费,可以求S个联通块中的最小生成树,求p个节点中s个联通块的最小生成树,只需要连p-s条边即可(请读者画一张图自己连连看)

算法实现:

1)预处理出两两之间的花费

2)跑一边Kruskal,求出s个联通块的MST

3)取最大值即可

详细细节见代码:

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstdio>
 5 using namespace std;
 6 struct node
 7 {
 8     int u,v;
 9     double w;
10 };
11 node f[200001];
12 bool cmp(node a,node b)
13 {
14     return a.w<b.w;
15 }
16 int s,p,parent[5005],num,x[501],y[501],sum;
17 double weight;
18 int find(int x)
19 {
20     if(parent[x]==x)return x;
21     else return parent[x]=find(parent[x]);
22 }
23 void Union(int R1,int R2)
24 {
25     int r1=find(R1),r2=find(R2);
26     parent[r1]=r2; 
27 }
28 int main()
29 {
30     cin>>s>>p;
31     for(int i=1;i<=p;i++)parent[i]=i;
32     for(int i=1;i<=p;i++)
33     {
34         cin>>x[i]>>y[i];
35     }
36     for(int i=1;i<=p;i++)
37     {
38         for(int j=i+1;j<=p;j++)
39         {
40             f[++sum].u=i;
41             f[sum].v=j;
42             f[sum].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
43             //cout<<f[sum].w<<endl;
44         }
45     }
46     sort(f+1,f+sum+1,cmp);
47     for(int i=1;i<=sum;i++)
48     {
49         int u=find(f[i].u),v=find(f[i].v);
50         if(u!=v)
51         {
52             num++;
53             weight+=f[i].w;
54             //cout<<weight<<endl;
55             weight=f[i].w;
56             Union(u,v);
57         }
58         if(num==p-s)break;
59     }
60     printf("%.2lf",weight);
61     return 0;
62 }
View Code

 

 

 

  

posted @ 2019-06-03 19:15  shao0320  阅读(241)  评论(0编辑  收藏  举报
****************************************** 页脚Html代码 ******************************************