在这里插入代码片
```#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
typedef struct ENode{
int start;
int end;
double weight;
}ENode;
ENode E[250005];
int p[505]; //结点的前驱
int x[505],y[505]; //记录点的坐标的数组
double len[250005]; //记录组成最短树的路的长度
int q;
void Init(int n){ //初始化,每个结点都单独成树
for(int i=1;i<=n;i++)
p[i]=i;
}
int Find(int i){ //找根节点
if(p[i]==i)
return i;
else
return p[i]=Find(p[i]);//将该路径上的结点的前驱结点都改为根节点
}
int Union(int a,int b){ //将ab在的树合为一棵树
if(Find(a)==Find(b))
return 0;
else{
p[Find(b)]=Find(a); //b的根节点的前驱改为a的根节点
return 0;
}
}
void Kruskal(int n,int m){// n是结点个数,m是边的总数
q=0; //作为边的下标
Init(n);
for(int i=1;i<=m;i++){
int a=Find(E[i].start);
int b=Find(E[i].end);
if(a!=b){
Union(a,b);
len[++q]=E[i].weight;
}
}
}
double dist(int a,int b){
return sqrt((double)(x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
bool cmp(ENode a,ENode b){
return a.weight<b.weight;
}
int main(){
int N;
cin>>N;
while(N--){
int S,P;
cin>>S>>P;
int cnt=0;
for(int i=1;i<=P;i++){
cin>>x[i]>>y[i];
}
for(int i=1;i<=P;i++)
for(int j=i+1;j<=P;j++){
E[++cnt].weight=dist(i,j);
E[cnt].start=i;
E[cnt].end=j;
}
sort(E+1,E+1+cnt,cmp);
q=0;
Kruskal(P,cnt);
int to=q-S+1; //有S-1个地方是可以用卫星通信的
printf("%.2f\n", len[to]);
}
return 0;
}
## 标题POJ2349 Kruskal算法的变形
Kruskal算法变形 poj2349
于 2022-05-30 20:56:12 首次发布
本文介绍了一种使用Kruskal算法变形来寻找具有特定卫星通信限制的最短树的方法。通过初始化每个节点并进行并查集操作,逐步合并不同树以构建最短树,并计算出满足条件的最短距离。程序中还包含了二维坐标点间的距离计算以及边的排序策略,以确保找到最优解。
摘要由CSDN通过智能技术生成