最小生成树Kruskal算法

Posted Mr^Kevin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树Kruskal算法相关的知识,希望对你有一定的参考价值。

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算法的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树详解 prim+ kruskal代码模板

(最小生成树)Kruskal算法

最小生成树及Prim算法及Kruskal算法的代码实现

最小生成树算法:Kruskal算法 Prim算法

最小生成树

图解:如何实现最小生成树(Prim算法与Kruskal算法)