kruskal算法:
1).记Graph中有v个顶点,e个边
2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边
3).将原图Graph中所有e个边按权值从小到大排序
4).循环:从权值最小的边开始遍历每条边 直至图Graph中所有的节点都在同一个连通分量中
if 这条边连接的两个节点于图Graphnew中不在同一个连通分量中
添加这条边到图Graphnew中
kruskal与prim的区别:
1.Kruskal算法因为只与边相关,适合求稀疏图的最小生成树;prim算法只与顶点有关,适合求稠密图的最小生成树
2.Kruskal算法在效率上要比Prim算法快,因为Kruskal只需要对权重边做一次排序,而Prim算法则需要做多次排序
3.prim适合采用邻接矩阵存储,Kruskal适合采用边目录方式存储(输入时直接告诉A—B的权值为x)
struct Edge //边结构体
{
int u,v,w;//边的2个端点(始点和终点)及其权值
}e[maxn];
void makeSet() //点从1开始编号
{
for(int i = 1;i <= n; i++)
{
fa[i] = i;
}
}
int Find(int x)//找x所在的集合
{
if(x != fa[x])
fa[x] = Find(fa[x]);
return fa[x];
}
bool cmp(Edge x,Edge y)
{
return x.w<y.w;
}
//这里的n代表节点数,给节点初始化,m代表边数,需要给边数排序
int kruskal()
{
int ans=0,cnt=0;
makeSet();//初始化父亲
sort(e+1,e+m+1,cmp);
for(int i = 1;i <= m; i++)//边从1开始编号
{
int fx = Find(e[i].u);//找到每条边的始点所在的集合
int fy = Find(e[i].v);//找到每条边的始点所在的集合
if(fx != fy) //如果不在一个集合里
{
fa[fx] = fy;
ans += e[i].w;
cnt++;//表示最小生成树的边的数量
}
}
return ans;
}