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