Kruscal算法:
Kruscal算法是加边。
记录每条路的权值,然后每次都选择权值最小的边加入集合,同时选中的每条边的两个点也用并查集合并,
直到所有的点都被加入了,就是最小生成树。
复杂度:
时间复杂度只和边有关系,O(E * logE)。
对于克鲁斯卡尔算法的最小生成树,我的理解是在并查集的基础上,对每个值的权值进行排序在判断是否形成一个环的操作
对于不了解并查集的小伙伴可以去看下并查集
附上一个大佬的博客,写的通俗易懂,还很有趣
https://blog.youkuaiyun.com/u013546077/article/details/64509038
下面是hdu 1863的代码
克鲁斯卡尔的模板题
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct node{
int x,y,v;
}p[107];
int n,m;
int pre[107];//记录i的上级;
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
return r;
}
void join(int x,int y)
{
int fa=find(x);
int fb=find(y);
if(fa!=fb)
pre[fa]=fb;
}
void kruskal()
{
int sum=0;
int i,j=0;
for(i=0;i<n;i++)
{
if(find(p[i].x)!=find(p[i].y))//判断是否是个环
{
join(p[i].x,p[i].y );
sum+=p[i].v ;
j++;
}
}
if(j==m-1) printf("%d\n",sum);
else
printf("?\n");
}
bool cmp(node a,node b)
{
return a.v<b.v ;
}
int main()
{
while(scanf("%d%d",&n,&m),n!=0)
{
for(int i=0;i<=m;i++)//初始化数组
pre[i]=i;
for(int i=0;i<n;i++)
scanf("%d%d%d",&p[i].x ,&p[i].y,&p[i].v );
sort(p,p+n,cmp);
kruskal();
}
}