最小生成树-Kruskal算法

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
Output示例
37

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>

using namespace std;

const int MAXN=100100;

struct edge{ //结构体存放边的权值信息 
	int x,y,w;
	edge(int x=0,int y=0,int w=0):x(x),y(y),w(w){
	}
};edge e[MAXN];
int fa[MAXN];
int getFather(int x){//寻找父节点 
	if(x==fa[x])return x;
	else return fa[x]=getFather(fa[x]);
}
bool cmp(const edge& e1,const edge& e2){//权值比较函数
    return e1.w < e2.w;
}
int kruscal(int M,int N){//核心算法 
	sort(e,e+M,cmp);//按权值对各边从小到大排序 
	int cnt=N,ans=0;//cnt标记现有的划分 
	for(int i=0;i<N;++i)fa[i]=i;//初始化 
	for(int i=0;i<M;++i){
		int t1=getFather(e[i].x);
		int t2=getFather(e[i].y);
		if(t1!=t2){//如果两点父节点不同,则可连接 
			fa[t1]=t2;
			ans+=e[i].w;//最小生成树的长度 
			//ans=max(ans,e[i].w);//最小生成树最大长度的边 
			cnt--; //若两点可以相连 ,则划分减一 
			if(cnt==1)break;//如果只有一个划分,则最小生成树已经得出,则退出 
		}
	}
	return ans;
}
int main(){
	int M,N;
	while(scanf("%d%d",&N,&M)!=EOF){
	for(int i=0;i<M;i++){//用结构体数组记录各边 
	int x,y,w;
	cin>>x>>y>>w;
	e[i].x=x;
	e[i].y=y;
	e[i].w=w;
	 
}
	cout<<kruscal(M,N)<<endl;
}
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值