前言
克鲁斯卡尔的思路非常简单,适用于稀疏图的最小生成树问题的解决。
一、题目陈述
二、解决思路
1.将所有边按权重从小到大排序,O(mlogm)
。sort。
2.枚举每条边,如果起点和终点不连通,则将这条边加入到集合中。O(m)
。并查集。
三、代码实现
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10,M=2*N;
int n,m;
// 并查集
int p[N];
struct Edge{
int a,b,w;
// 重载小于运算符
bool operator< (const Edge &W) const {
return w<W.w;
}
}edges[M];
int find(int x) {
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main() {
cin>>n>>m;
for(int i=0;i<m;i++) {
int a,b,w; cin>>a>>b>>w;
edges[i]={a,b,w};
}
sort(edges,edges+m);
// 初始化并查集
for(int i=1;i<=n;i++) p[i]=i;
// 从小到大枚举所有边
int res=0,cnt=0;
for(int i=0;i<m;i++) {
int a=edges[i].a,b=edges[i].b,w=edges[i].w;
a=find(a),b=find(b);
if(a!=b) {
p[a]=b;
res += w;
cnt++;
}
}
if(cnt<n-1) puts("impossible");
else cout<<res<<endl;
return 0;
}
总结
简单优美的最小生成树算法,结合了并查集数据结构。