Kruskal算法实际上是 贪心+并查集的结合,只要会了并查集,那么这个算法一点难度都没有了,,,
下来是讲解下这个算法的具体实现步骤和时间复杂度,,首先,对于一个具有n个顶点的图,我们知道至少会有n-1条边,使这个图不构成回路,好了,那么这n-1条边刚好可以构成一棵树,既然要求造价最小的一棵树,那么我们就利用贪心的思想,先对每一条边的权值进行从小到大排序,然后,依次从小到大开始选边,选出来的边在这支离破碎的n个顶点上进行树的构建,如果我们在连边的过程中遇到了两个顶点同属于一个集合的情况,那么我们就利用并查集来预先判定,,让这种情况尽量不要发生,,,通过MlogM的时间,我们就可以构成这棵最小生成树了。。
代码:
# include<cstdio>
# include<iostream>
# include<algorithm>
# include<cstring>
# include<string>
# include<cmath>
# include<queue>
# include<stack>
# include<set>
# include<map>
using namespace std;
# define inf 999999999
# define MAX 2333
int f[10];
int n,m;
int ans;
int cnt;
struct edge
{
int u;
int v;
int w;
}e[MAX];
int cmp ( edge a,edge b )
{
return a.w < b.w;
}
int getf( int v )
{
if ( f[v]==v )
return v;
else
{
f[v] = getf( f[v] );
return f[v];
}
}
int merge ( int v,int u )
{
int t1 = getf(v);
int t2 = getf(u);
if ( t1!=t2 )
{
f[t2] = t1;
return 1;
}
return 0;
}
int main(void)
{
cin>>n>>m;
for ( int i = 1;i <= m;i++ )
{
cin>>e[i].u>>e[i].v>>e[i].w;
}
sort(e+1,e+1+m,cmp);
for ( int i = 1;i <= n;i++ )
{
f[i] = i;
}
for ( int i = 1;i <= m;i++ )
{
if ( merge( e[i].u , e[i].v ) )
{
cnt++;
ans+=e[i].w;
}
if ( cnt == n-1 )
{
break;
}
}
cout<<ans<<endl;
return 0;
}