上午学长讲的最小生成树,找个模板题顺手练一下,用的是kruskal算法.
prim算法适合处理边数较多,顶点较少的情况,而kruskal算法则更适合处理边数较少,顶点较多的情况.
代码已AC.
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<time.h>
using namespace std;
struct dott{//存每个点的坐标,以及自己是第几个点
int x;int y;
int number;
}dot[110];
struct edg{//存储两个点,以及他们之间的距离;
int dot1;
int dot2;
double length=999999999.9;
}edge[6000];
int comp(const edg &a,const edg &b){
return a.length<b.length;
}
int pre[110];//进行并查集的处理
int Find(int x){//查找根节点+路径压缩
int p,a;
p=x;
while(x!=pre[x])
x=pre[x];
while(p!=x){
a=pre[p];
pre[p]=x;
p=a;
}
return x;
}
void mix(int dot1,int dot2){//合并两点
int a,b;
a=Find(dot1);
b=Find(dot2);
if(a!=b)
pre[a]=b;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
pre[i]=i;//所有根节点初始化为自身
}
double a[110],b[110];
for(int i=0;i<n;i++){
scanf("%lf %lf",&a[i],&b[i]);
dot[i].x=a[i];dot[i].y=b[i];
dot[i].number=i;
}
int f=0;
for(int i=0;i<n-1;i++){//对所有两点距离进行计算并保存
for(int j=i+1;j<n;j++){
double len=sqrt((dot[j].x-dot[i].x)*(dot[j].x-dot[i].x)+(dot[j].y-dot[i].y)*(dot[j].y-dot[i].y));
edge[f].dot1=i;edge[f].dot2=j;edge[f].length=len;f++;
}
}
sort(edge,edge+f,comp);//对所有距离进行排序
double sum=0.0;
for(int i=0;i<f;i++){
if(Find(edge[i].dot1)!=Find(edge[i].dot2)){
mix(edge[i].dot1,edge[i].dot2);
sum+=edge[i].length;
}
}
printf("%.2lf\n",sum);
}
return 0;
}