最小生成树算法Kruskal详解
2018-03-26 18:03
211 查看
一、算法概述
最小生成树(Minimum Spanning Tree,MST):或者称为最小代价树Minimum-cost Spanning Tree:对无向连通图的生成树,各边的权值总和称为生成树的权,权最小的生成树称为最小生成树。最小生成树问题其实就是求一棵怎样的树可以遍历每个节点,且总权值最小。
本文介绍用Kruskal算法解决最小生成树问题。
二、算法步骤
1、将连通图看做无边的散点,每个散点即为自己的父节点。2、将每条边按照从小到大的顺序排列,每次从中取最小的边加入散点图。
3、加入时需要满足两个点连接后不能出现连通图。
要想确保不出现连通图,则两个点在连接前应属于不同的集合(树)。所以需要判定它们是否在一个集合中。
方法是使用并查集,关于并查集的内容请参照:https://blog.csdn.net/hacker_wind/article/details/79687134。
4、重复步骤直至散点图变为连通图。所以定义一个计数器,当计数器的数值等于节点个数时,程序退出。
三、代码及测试样例
给出如上图所示连通图,求其最小生成树。由图可知一共有6个节点,10条边。初始化其为散点图,将边按照权值由小到大加入图中,则顺序为AC,DF,BE,CF,当BC、AD、AC权值都为5时,程序会按照输入顺序先后进行判定。假设输入顺序为AD、BC、CD,则发现ACDF构成了连通图,所以将AD边舍去。BC边加入后未构成连通图,且所有点实现了连通,则程序结束。
最后得到的最小生成树如上图所示。代码如下:#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
//#define PI 3.14159265358979323
#define inf 0x3f3f3f3f
int pre[1005];//并查集中用于记录父节点的数组
int n,m;
int ans;
struct edges
{
int u,v,w;//u、v为一条边的两个节点,w为边的权重
}e[1005];
bool cmp(edges a,edges b)
{
return a.w<b.w;//对边进行排序
}
void Init()//初始化散点图,每个散点的父节点为自己本身
{
for(int i=0;i<m;i++)
pre[i]=i;
}
int Find(int x)//并查集中寻找父节点的函数
{
int r=x;
while(pre[r]!=r)
r=pre[r];
return r;
}
void join(int a,int b)//将两个不在同一集合的点连通起来
{
pre[b]=a;
}
void kruskal()
{
int sumw=0;//权值总和
int n=0;//计数器,记录加入树中节点的个数
Init();
int u,v;
for(int i=0;i<m;i++)
{
u=e[i].u;
v=e[i].v;
int fx=Find(u);
int fy=Find(v);
if(fx!=fy)
{
cout<<u<<" "<<v<<" "<<e[i].w<<endl;
sumw+=e[i].w;
n++;
join(fx,fy);
}
if(n==m-1)
break;
}
cout<<"The weight of MST is "<<sumw<<endl;
}
int main()
{
cin>>n>>m;//n为节点总个数,m为边数
for(int i=0;i<m;i++)
cin>>e[i].u>>e[i].v>>e[i].w;
sort(e,e+m,cmp);
kruskal();
return 0;
}
/*
测试样例
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
*/运行结果如下图所示:
相关文章推荐
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- 最小生成树之克鲁斯卡尔(Kruskal)算法实现,代码详解!!!!
- Kruskal(克鲁斯卡尔) 最小生成树 算法详解+模板
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- Kruskal最小生成树算法详解,以及java源代码
- 最小生成树算法——Kruskal
- 最小生成树两种算法。kruskal和prim
- java实现图的最小生成树(森林)MST克鲁斯卡尔(Kruskal)算法
- 最小生成树算法(下)——Kruskal(克鲁斯卡尔)算法
- C++代码,数据结构-最小生成树的两个算法,Prime&Kruskal
- poj 1751 Highways 最小生成树之Kruskal(克鲁斯卡尔)算法
- 最小生成树两个重要的算法:Prim 和 Kruskal
- 最小生成树——Kruskal(克鲁斯卡尔)算法
- HDU-1875 畅通工程再续-1162 - Eddy's picture(最小生成树,Kruskal 算法实现 )
- kruskal与prim最小生成树算法
- 拓扑排序 详解 + 并查集 详解 + 最小生成树(MST)详解 【普利姆算法 + 优先队列优化 & 克鲁斯卡尔算法】
- 图论-带权图的最小生成树(Kruskal)算法
- 最小生成树(MST) Kruskal 算法
- 最小生成树(qsort+并查集+克鲁斯卡尔(Kruskal)算法)
- BZOJ 2654 tree 详解(最小生成树 kruskal 二分)