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;
}