最小生成树

最小生成树

该算法分为两种主要算法,分别是以边权来贪心的即(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;
}
posted @ 2026-07-05 16:36  diaitor  阅读(3)  评论(0)    收藏  举报