最小生成树
顾名思义,最小生成树就是求一个边带权的连通图里边的权值之和最小的一个树。
所以一棵树就自然而然的,它本身就是它的最小生成树了。
Kruskal
Kruskal求最小,从最小的边开始找。
找最小的边,可以读入所有的边排序;但是很快就出现了一个问题:树的边数为n-1,要确保选入的最小的边没有重复连,没有漏连需要判断:这条边要连接的两个点是否已经有其他的边连接,直接或间接都算。所以我们最好开一个结构体方便存一条边。利用并查集,判断这两个点是不是在同一个集里面就可以决定连不连这条边了。
接下来是模板代码:
#include<bits/stdc++.h>
using namespace std;
int fa[5010],n,m,ans=0;
struct edge
{
int u,v,w;
}e[200005];
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
int get(int x)
{
if(fa[x]==x) return x;//x的根为它本身,x就是该集的根
return fa[x]=get(fa[x]);//路径压缩
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
fa[i]=i;//初始化
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<=m;i++)
{
int u=get(e[i].u);//找根
int v=get(e[i].v);
if(u==v) continue;
fa[u]=v;
cout<<e[i].u<<" "<<e[i].v<<endl;
ans+=e[i].w;
}
cout<<ans<<endl;
return 0;
}