Freckles(Kruskal解决最小生成树问题)——C++实现

放肆的年华 提交于 2020-02-16 23:34:11

题目链接:

https://www.nowcoder.com/practice/41b14b4cd0e5448fb071743e504063cf?tpId=40&tqId=21371&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking

代码如下:

#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;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!