[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 
#include 
#include 
#include 
#include 
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 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;jdouble 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<
        }
    }
    kruskal();
    printf("%.2lf",ne[top-s].val);
}

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