学习总结17

# 无线通讯网

## 题目描述

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

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

任意两个配备了一条卫星电话线路的哨所(两边都有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过 D,这是受收发器的功率限制。收发器的功率越高,通话距离 D 会更远,但同时价格也会更贵。

收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个 D。你的任务是确定收发器必须的最小通话距离 D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。

## 输入格式

第一行,2 个整数 S 和 P,S 表示可安装的卫星电话的哨所数,P 表示边防哨所的数量。

接下里 P 行,每行两个整数 x,y 描述一个哨所的平面坐标 (x, y),以 km 为单位。

## 输出格式

第一行,1 个实数 D,表示无线电收发器的最小传输距离,精确到小数点后两位。

## 样例 #1

### 样例输入 #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。

解题思路

这道题的数据比较小,我们可以直接把每一个哨所之间距离给算出来,然后按距离从小到大排序,利用Kruskal 来生成树就行了(只要链接p-s个节点就行了,后面就可以用卫星电话了)。因为我们是从小到大来建立的,于是最后一个节点和前一个节点的距离就是最大距离。

代码

#include
using namespace std;
int a[510],b[510];
int s,p,n;
struct ss
{
    int x;
    int y;
    double jl;
}g[510*510];
int j[510];
int j2[510];
int find1(int x)
{
    if(j[x]==x)
        return x;
    return j[x]=find1(j[x]);
}
int cmp(ss x,ss y)
{
    return x.jlj2[y]) j[y]=x;
    else
    {
        j[x]=y; j2[y]++;
    }
}
int main()
{
    int x,y,t=0;
    double min1;
    scanf("%d%d",&s,&p);
    for(x=1;x<=p;x++)
    {
        scanf("%d%d",&a[x],&b[x]);
        j[x]=x;
    }
    for(x=1;x<=p;x++)
    {
        for(y=1;y<=p;y++)
        {
            g[++n].jl=sqrt((a[x]-a[y])*(a[x]-a[y])+(b[x]-b[y])*(b[x]-b[y]));
            g[n].x=x;
            g[n].y=y;
        }
    }
    sort(g+1,g+n+1,cmp);
    for(x=1;x<=n;x++)
    {
        if(t==p-s)
            break;
        if(find1(g[x].x)!=find1(g[x].y))
        {
            unit(g[x].x,g[x].y);
            t++;
            min1=g[x].jl;
        }
    }
    printf("%.2lf",min1);
    return 0;
}

你可能感兴趣的:(学习,算法)