[kruskal]无线网络

题目描述 Description
国防部计划用无线网络连接若干个边防哨所。2 种不同的通讯技术用来搭建无线网络;
每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都

输入描述 Input Description
输入数据第1 行,2 个整数S 和P,S 表示可安装的卫星电话的哨所
数,P 表示边防哨所的数量。接下里P 行,每行两个整数x,y 描述一个哨所的平面坐标
(x; y),以km 为单位。

输出描述 Output Description
第1 行,1 个实数D,表示无线电收发器的最小传输距离,

样例输入 Sample Input
2 4
0 100
0 300
0 600
150 750

样例输出 Sample Output
212.13

数据范围及提示 Data Size & Hint
对于20% 的数据:P = 2,S = 1
对于另外20% 的数据:P = 4,S = 2
对于100% 的数据保证:1 S 100,S < P 500,0 x,y 10000。


思路:生成图后直接暴力kruskal,去掉最后S个点,最后就是最优答案,即最大边。 使用优先队列e存边,ne数组存生成树中每条边

#include <cstdio>
#include <iostream>
#include <memory.h>
#include <cmath>
#include <queue>
using namespace std;
struct edge{
    int fr,to;
    double val;
    edge(void):fr(0),to(0),val(0){}
    edge(int fr,int to,double val):fr(fr),to(to),val(val){}
};
bool operator<(edge a,edge b){
    return a.val>b.val;
}
const int maxn=10000;
int s,p;
int fa[maxn];
int find(int i){
    if (i==fa[i])
        return fa[i];
    return fa[i]=find(fa[i]);
}
priority_queue<edge> e;
edge ne[maxn];
int top=0;
int vts[maxn][2];
void kruskal(void){
    int n=p-1;
    while (n){
        edge etop=e.top();
        e.pop();
        int u=etop.fr,v=etop.to;
        if (find(u)!=find(v)){
            fa[fa[v]]=fa[u];
            ne[top++]=etop;
            n--;
        }
    }

}
int main(void){
    scanf("%d %d",&s,&p);
    for (int i=1;i<=p;i++){
        fa[i]=i;
        int fr,to;
        double val;
        scanf("%d%d",&vts[i][0],&vts[i][1]);
        for (int j=1;j<i;j++){
            double dx=vts[i][0]-vts[j][0];
            double dy=vts[i][1]-vts[j][1];
            val=sqrt(dx*dx+dy*dy);
            edge e1(i,j,val);
            edge e2(j,i,val);
            e.push(e1);
            e.push(e2);
//          cout<<val<<endl;
        }
    }
    kruskal();
    printf("%.2lf",ne[top-s].val);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值