#include<stdio.h>
#include<stdlib.h>
typedef struct{
int u,v;//存储边的端点序号
int w; //存储边的权值
}Sample;
int p[100];//存储图中点的序号
Sample r[100];//定义结构体数组存储有权无向图
int points,edges;//图的点数与边数
int cmp(const void *a,const void *b){
//按照权值w从小到大将结构体数组排序
return (*(Sample*)a).w-(*(Sample*)b).w;
}
int find(int x){
//查找结点x所在树的根节点
return p[x]==x?x:p[x]=find(p[x]);
}
int Kruskal(){
//改进的克鲁斯卡尔算法
int ans=0;//初始化最小权值
for(int i=0;i<100;i++)
{
p[i]=i;//初始化并查集
}
for(int i=0;i<edges;i++)
{
int x=find(r[i].u);
int y=find(r[i].v);//找出当前边两个端点所在集合编号
if(x!=y)
{
ans+=r[i].w;
p[x]=y;//如果在不同集合,合并之
}
}
return ans;
}
int main()
{
FILE* in=fopen("input.txt","rt");
fscanf(in,"%d %d",&points,&edges);
for(int i=0;i<edges;i++)
{//读入图信息
fscanf(in,"%d %d %d",&r[i].u,&r[i].v,&r[i].w);
}
qsort(r,edges,sizeof(r[0]),cmp);//快速排序
for(int i=0;i<edges;i++)
{//输出图信息验证排序效果
printf("%d %d %d\n",r[i].u,r[i].v,r[i].w);
}
printf("%d\n",Kruskal());
fclose(in);
system("pause");
return 0;
}
最小生成树(qsort+并查集+克鲁斯卡尔(Kruskal)算法)
最新推荐文章于 2024-06-05 10:10:53 发布