最小生成树模板

题目

最小生成树模板

Kruskal:

时间复杂度:\(O(M\log M)\)

#include<bits/stdc++.h>
using namespace std;
int N,M,f[5010],ans;
struct node{
	int X,Y,Z;
}e[200010];
bool cmp(node x,node y){
	return x.Z<y.Z; 
}
void init(){
	for(int i=1;i<=N;i++) f[i]=i;
}
int Find(int x){
	return f[x]==x?x:f[x]=Find(f[x]);
}
void hebing(int x,int y){
	f[Find(x)]=Find(y);
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>N>>M;init();
	for(int i=1;i<=M;i++) cin>>e[i].X>>e[i].Y>>e[i].Z;
	sort(e+1,e+1+M,cmp);//读入图信息,排序边
	for(int i=1;i<=M;i++){
		int u=e[i].X,v=e[i].Y,w=e[i].Z;
		if(Find(u)!=Find(v)){//如果u和v不在同一个集合,则合并
			ans+=w;//将边权加入最后答案
			hebing(u,v);
		}
	}
	for(int i=1;i<=N;i++){
		if(Find(i)!=Find(1)){
			cout<<"orz";//判断是否最终剩下一个集合,如果不是,输出“orz”
			return 0;
		}
	} 
	cout<<ans;
	return 0;
}

Prim(堆优化):

时间复杂度:\(O((N+M)\log N)\)

#include<bits/stdc++.h>
using namespace std;
using pii=pair<int,int>;
const int MAXN=5005,MAXM=400005; 
int N,M,hd[MAXN],ver[MAXM],nxt[MAXM],w[MAXM],tot,dis[MAXN];
bool vis[MAXN];
void add(int u,int v,int c){
	ver[++tot]=v;w[tot]=c;nxt[tot]=hd[u];hd[u]=tot;
	ver[++tot]=u;w[tot]=c;nxt[tot]=hd[v];hd[v]=tot;
}
int Prim(){
	priority_queue<pii,vector<pii>,greater<pii> > q;//小根堆,存(距离,节点编号)
	memset(dis,0x7f,sizeof(dis));//初始化距离
	dis[1]=0;
	q.push({0,1});
	int ans=0,cnt=0;//cnt记录加入生成树的节点数
	while(q.size()&&cnt<N){
		int d=q.top().first,u=q.top().second;q.pop();
		if(vis[u]) continue;//为旧值或已访问
		vis[u]=true;
		ans+=d;cnt++;
		for(int i=hd[u];i;i=nxt[i]){//遍历u的所有出边,尝试更新未访问节点的dis
			int v=ver[i],c=w[i];
			if(!vis[v]&&c<dis[v]){
				dis[v]=c;
				q.push({c,v});
			}
		}
	}
	return (cnt==N)?ans:-1;//如果cnt<n,说明图不连通
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>N>>M;
	for(int i=1,X,Y,Z;i<=M;i++){
		cin>>X>>Y>>Z;
		add(X,Y,Z);
	}
	int res=Prim();
	if(res==-1) cout<<"orz";
	else cout<<res;
	return 0;
}
posted @ 2026-08-15 10:39  decentz  阅读(8)  评论(0)    收藏  举报