码迷,mamicode.com
首页 > 编程语言 > 详细

最小生成树Kruskal算法

时间:2017-08-22 20:52:59      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:log   返回   blog   stl   连通   har   sharp   oid   自定义   

Kruskal算法是生成最小生成树的一种好的算法,巧妙地运用了并查集。

#include<cstdio>
#include<algorithm> //调用STL库,使用sort排序 
using namespace std;
struct s {int u;int v;int w;}; //定义结构体,用于储存边的起点,终点和权值 
int N,M,ml,fa[5005]; //定义点数,边数,最小生成树的权值和,并查集代表元素 
s e[200005]; //定义边集 
bool cmp(s a,s b) {return a.w<b.w;} //自定义比较函数,将边按权值排序 
int f(int i) { //定义函数用于查询是否同属于同一集合 
	if(fa[i]==i) return i; //如果本元素指向的元素是其本身,说明该元素为集合的代表元素,则返回 
	else return fa[i]=f(fa[i]); //否则更新元素指向的元素,使其直接指向集合的代表元素 
}
void to_small() { //定义函数用于生成最小生成树 
	sort(e,e+M,cmp); //按权值排序边 
	for(int t=1;t<=N;++t) fa[t]=t; //初始化并查集,使元素指向本身 
	for(int t=1;t<=M;++t) { //遍历每一条边 
		if(f(e[t].u)!=f(e[t].v)) { //如果边的起点和终点不属于同一集合 
			ml+=e[t].w; //将该边加入最小生成树 
			fa[f(e[t].u)]=fa[f(e[t].v)]; //让边的起点和终点处于同一集合 
		}
	}
	printf("%d",ml); //输出最小权值和 
}
int main() {
	scanf("%d%d",&N,&M); //读入点数,边数 
	for(int t=1;t<=M;++t) scanf("%d%d%d",&e[t].u,&e[t].v,&e[t].w); //读入每条边的起点,终点,权值 
	if(M<N-1) printf("orz"); //如果图不连通,输出org 
	else to_small(); //如果图连通,则生成最小生成树 
	return 0;
}

 

最小生成树Kruskal算法

标签:log   返回   blog   stl   连通   har   sharp   oid   自定义   

原文地址:http://www.cnblogs.com/Mr94Kevin/p/7413499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!