/**
*
* Coder: LinX 2017-7-16
*
* 内容: 使用Kruskal算法计算无向图的最小生成树
*
* 说明: 此算法复杂度只与图的边数有关,因此适合于稀疏图
*/
#include <stdio.h>
#include <stdlib.h>
int enums;
typedef struct
{
int start,end; //边的两个顶点
int weight; //边的权值
}Road;
int Kruskal(Road road[],int v[]);
int getRoot(int v[],int vt);
int main()
{
int i,start,end,weight,v[100];
Road road[100];
printf("输入边的条数: ");
scanf("%d",&enums);
printf("输入边信息(输入一对顶点的位置)及权值: ");
/*初始化road数组和并查集*/
for(i=0;i<enums;i++)
{
scanf("%d%d%d",&start,&end,&weight);
road[i].start=start;
road[i].end=start;
road[i].weight=weight;
v[i]=i; //刚开始每个节点都是一棵树
}
return 0;
}
int Kruskal(Road road[],int v[])
{
int i,a,b,sum=0;
sort(road); //使road数组按照权值大小排序,这里没有写函数
//排好序之后从第一条边(权值最小)开始,取起点和终点,更新并查集(其实就是树)
// 更新方法:1.如果两个顶点不再一棵树上,那么将起点的根节点作为根节点,终点的根节点作为子节点(只需将并查集数组的子节点
//的值改成起点的值) 2.如果两个顶点在一棵树上,那么跳过。
//判断是否在一棵树上的方法:算出起点和终点的根节点,如果根节点相同那么就在一棵树,否则不在
for(i=0;i<enums;i++)
{
a=getRoot(v,road[i].start);
b=getRoot(v,road[i].end);
if(a!=b)
{
v[b]=a;
sum=sum+road[i].weight;
}
}
return sum;
}
int getRoot(int v[],int vt)
{
while(vt!=v[vt])
{
vt=v[vt];
}
return vt;
}
Kruskal算法(不能运行)
最新推荐文章于 2022-04-15 09:31:00 发布