最小生成树(kruskal)

题目描述

输入一个连通无向网络,输出它的最小生成树的权值和

输入

输入文件第一行为n和m(n,m<=20),表示n个顶点和m条边,接下来m行,每行vi,vj,k(0 < k <=100),表示vi到vj有条边,而且权值是k

输出

输出文件仅一行,为最小生成树的权值和

输入样例

4 5
1 2 2
1 3 1
2 3 5
3 4 2
4 1 3

输出样例

5

裸裸的模板题,就当练代码了。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=101;
int v[MAXN],w[MAXN],r[MAXN],e[MAXN],f[MAXN];//v,w表示这条边的两个端点,r表示边的序号,f表示父节点,e表示边权。
int n,m;
int find(int root){//查找根结点并路径压缩
	int son,temp;
	son=root;
	
	while(f[root]!=root)
	root=f[root];
	
	while(f[son]!=root){
		temp=f[son];
		f[son]=root;
		son=temp;
	}
	return root;
}

bool cmp(const int a,const int b){//按边权从小到大排序
	return e[a]<e[b];
}

void Kruscal(){
	int ans=0;
	for(int i=1;i<=m;i++)//初始化边的序号
	r[i]=i;
	for(int i=1;i<=n;i++)//初始化父节点
	f[i]=i;
	sort(r+1,r+m+1,cmp);
	for(int i=1;i<=m;i++){
		int s=r[i];
		int a=find(v[s]);
		int b=find(w[s]);
		if(a!=b){//如果端点不在同一集合的话就加入
			f[a]=b;//合并2个集合
			ans+=e[s];//加上边的权值
		}
	}
	cout<<ans; 
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		v[i]=a;
		w[i]=b;
		e[i]=c;
	}
	Kruscal();
}


猜你喜欢

转载自blog.csdn.net/qq_41734244/article/details/80025291