最小生成树
最小生成树
该算法分为两种主要算法,分别是以边权来贪心的即(Kruskal)和以点权来贪心的(Prim)算法
1.Kruskal
//Kruskal
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
struct edge{
int u,v,w;
};
edge e[N];
bool cmp(edge x,edge y){
return x.w<y.w;
}
int fa[N];
void init(int n){
for(int i=1;i<=n;i++){
fa[i]=i;
}
}
int find(int x){
if(fa[x]==x){
return x;
}else{
fa[x]=find(fa[x]);
return fa[x];
}
}
void merge(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
fa[fx]=fy;
}
}
int main(){
int n,m;
cin>>n>>m;
init(n);
for(int i=1;i<=m;i++){
cin>>e[i].u>>e[i].v>>e[i].w;
}
sort(e+1,e+1+m,cmp);
int cnt=0,sum=0;
for(int i=1;i<=m;i++){
int u=e[i].u;
int v=e[i].v;
int w=e[i].w;
if(find(u)!=find(v)){
merge(u,v);
cnt++;
sum+=w;
}
}
if(cnt!=n-1){
cout<<"orz";
return 0;
}
cout<<sum;
return 0;
}
2.Prim
#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
const int N=5e3+10;
vector<pii>g[N];
bool vis[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
priority_queue<pii,vector<pii>,greater<pii>>q;
q.push({0,1});
int sum=0;
int cnt=0;
while(!q.empty()){
auto[w,u]=q.top();
q.pop();
if(vis[u]){
continue;
}
vis[u]=1;
sum+=w;
cnt++;
for(auto[v,ww]:g[u]){
if(!vis[v]){
q.push({ww,v});
}
}
}
if(cnt<n-1){
cout<<"orz";
return 0;
}
cout<<sum;
return 0;
}

浙公网安备 33010602011771号