《最小生成树Kruscal算法、并查集代码》
前言:这是第一次不用到例题来写一个算法的博客hhh,我在看了网上好多好多好多资料后,总结到博客里。
一、Kruscal算法思想:
①我们做最小生成树题的时候,要用到一个边的结构体数组:
typedef struct stu ///边结构体
{
int u; //边起始节点
int v; //边结尾节点
int len; //边权值
}edge;
edge a[10005]; //边的结构体数组
②克鲁斯卡尔算法是通过依次在所有边中挑选出最小权值的边来相加,直到添加的边等于结点数-1 (当然,如果新添加的边形成了环,就丢弃它)
③所以我们要先将数组按照权值从小到大排序,可能这时有点小问题了,结构体怎么排序呢,那么我们要用到C++的sort和伪函数来实现了,首先我们要定义一个伪函数compareEdge:
bool compareEdge(edge a1,edge a2) ///伪函数
{
return a1.len < a2.len;
}
然后再使用sort():
sort(&a[1],&a[n+1],compareEdge); ///排序边权
(不太熟悉STL和伪函数的自己去补补课哦)
④现在我们从a[1]开始遍历数组,我们每次选边的时候要考虑它是否会形成环,通常需要用并查集去判断,下面来讲解一下并查集的思想:
※这里打一个比方:现在一共有3个人,2是1的同事,3是1的同事。
那我们怎么去判断这三个人各自是不是同事关系呢,我们用一个数组person[i]的值来表示第i个人的最上级boss是谁,起始时每个人的boss都是它自己即person[i] = i,比如2是1的同事,那么person[1] = 2,相当于2现在就是1的boss。3是1的同事,那么person[1] 又要等于 3了, 避免这种现象就要先找到1的boss,然后**将1的boss的“boss”**更新,实现关系的链接(我觉得像极了链表的思想),当前1的boss是2那么找到person[2],原来person[2]是它本身,现在要更新为3,这时我们想象到的结构是这样:
person数组应该是这样:
我们如何去查找到某个人的Boss呢?
int findHead(int x)