最小生成树
最小生成树
基本概念
最小生成树是用最小的代价来使这个图联通。
它输入的有连接两条边的代价,我们要在这个图是联通的情况下,付出的代价最小。
前置知识:并查集
Kruskal
基本概念
- 我们可以先把这写边按照代价排序。接着,我们依次从1到
枚举这个排好序数组中的元素,依次判断每条边是否已经相通,如果是,那就跳过,否则就连通两条边,并且将计数器加上连接这条边的代价。 - 题目还说,如果怎么都无法让这个图任意两点都联通,就输出
,那么就可以再用一个计数器,每次连接一条边就加以,表示这个图的边多了一条。最后如果这个计数器不等于 ,那就说明——这个图不联通!
代码
先定义一个结构体,里面存着
struct node{
int x,y,z;
};
接下来,输入这个结构体。
vector<node> r(n);
for(int i=0; i<n; i++){
cin>>r[i].x>>r[i].y>>r[i].z;
}
我们可以写一个并查集来判断两条变是否是联通的。
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
我们知道,要让这个代价最小,我们可以先按照代价
bool cmp(node x,node y){
return x.z<y.z;
}
stable_sort(r.begin(),r.end(),cmp);
int sum=0,cnt=0;
for(int i=0; i<m; i++){
if(find(r[i].x)!=find(r[i].y)){
fa[find(r[i].x)]=find(r[i].y);
sum=sum+r[i].z;
cnt++;
}
}
最后,我们知道,一个联通图的边是
if(cnt!=n-1){
cout<<"orz"<<endl;
}
else{
cout<<sum<<endl;
}
完整代码:
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
int fa[10010];
struct node{
int x,y,z;
};
bool cmp(node x,node y){
return x.z<y.z;
}
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++){
fa[i]=i;
}
vector<node> r(m);
for(int i=0; i<m; i++){
cin>>r[i].x>>r[i].y>>r[i].z;
}
stable_sort(r.begin(),r.end(),cmp);
int sum=0,cnt=0;
for(int i=0; i<m; i++){
if(find(r[i].x)!=find(r[i].y)){
fa[find(r[i].x)]=find(r[i].y);
sum=sum+r[i].z;
cnt++;
}
}
if(cnt!=n-1){
cout<<"orz"<<endl;
}
else{
cout<<sum<<endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具