题目链接:
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int MAXN=101;
struct Point{
double x;
double y;
int order;//作为点的序号,以便使用并查集
};//点结构体
struct Edge{
Point from;//起点
Point to;//终点
double distance;//距离
bool operator< (const Edge e) const{
return distance<e.distance;
}
};//边结构体
Edge edge[MAXN*MAXN];//边集
int father[MAXN];//父节点
int height[MAXN];//节点高度
void Initial(int n){ //初始化
for(int i=0;i<=n;i++){
father[i]=i;
height[i]=0;
}
}
int Find(int x){ //查找
if(x!=father[x]){
father[x]=Find(father[x]);//路径压缩
}
return father[x];
}
void Union(int x,int y){ //合并
x=Find(x);
y=Find(y);
if(x!=y){
if(height[x]<height[y]){
father[x]=y;
} else if(height[y]<height[x]){
father[y]=x;
} else{
father[y]=x;
height[x]++;
}
}
return;
}
double Kruskal(int n,int m){ //最小生成树算法
Initial(n);
double ans=0;//距离值
sort(edge,edge+m);//各点距离由小到大排序
for(int i=0;i<m;i++){
if(Find(edge[i].from.order)!=Find(edge[i].to.order)){ //两点不在同一个集合中
Union(edge[i].from.order,edge[i].to.order);
ans+=edge[i].distance;
}
}
return ans;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
Point p[n];
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i].order=i;//给点编号
}
int index=0;//边下标
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i<j){
edge[index].from=p[i];
edge[index].to=p[j];
edge[index].distance=sqrt((p[j].x-p[i].x)*(p[j].x-p[i].x)+(p[j].y-p[i].y)*(p[j].y-p[i].y));
index++;
}
}
}
double ans=Kruskal(n,index);
printf("%.2f\n",ans);
}
return 0;
}
来源:CSDN
作者:Aaron_1997
链接:https://blog.csdn.net/Aaron_1997/article/details/104348593