Kruskal算法简明
来源:互联网 发布:泽西岛网络暗语 编辑:程序博客网 时间:2024/06/05 19:01
Kruskal算法简明
Kruskal(克鲁斯卡)算法和Prim算法般用于解决最小生成树问题,网上还有一个Prim+Heap的算法,空间复杂度比较高,但是效率很高。
Kruskal理解起来感觉会比prim好理解一些,和prim一样需要结合贪心思想,只是Kruskal需要结合并查集来使用。
算法的大致思想就是,先把所有的点等地位的铺开,然后先找到两个距离最近的点,将它们连起来,然后再找两个距离最近的点,将它们连起来,直到所有的点都成为连通的,就完成了Kruskal算法的过程。
实现就是先把所有的边集储存起来,然后按照边的权值大小将所有边排一遍序,再然后从小往大开始扫,执行并查集的操作,如果这条边的左右两个点尚未连起来,就将它们连起来;如果两个点已经同属于同一个根了,就跳过这条边。直到所有的点都属于同一个根。
因为根据边的权值排序过,所以根据贪心的思想,最后得到的生成树一定是最小生成树。
看文字还是很晦涩,结合Jungle Roads - POJ 1251 - Virtual Judge这道经典例题的代码和注释来理解吧。
此外,并查集部分先理解自行百度吧,附上我自己的并查集模板:传送门
POJ 1251的AC代码:
#include <iostream>#include <algorithm>using namespace std;const int size = 128; int n;int father[size]; //樹根int rank[size]; //樹高//把每条边成为一个结构体,包括起点、终点和权值 typedef struct node{ int val; //權 int start; int end; }edge[size*size];//把每个元素初始化为一个集合 void make_set(){ for(int i = 0; i < n; i ++){ father[i] = i; rank[i] = 1; } return ;}//查找一个元素所在的集合,即找到祖先 int find_set(int x){ if(x != father[x]){ father[x] = find_set(father[x]); //遞歸壓縮路徑 } return father[x];}//合并x,y所在的两个集合:利用Find_Set找到其中两个//集合的祖先,将一个集合的祖先指向另一个集合的祖先。void Union(int x, int y){ x = find_set(x); y = find_set(y); if(x == y){ return ; } if(rank[x] < rank[y]){ //根據樹高維護兩個節點的父子關係,以優化查找速率 father[x] = find_set(y); } else{ if(rank[x] == rank[y]){ rank[x] ++; } father[y] = find_set(x); } return ;}bool cmp(pnode a, pnode b){ return a.val < b.val; }int kruskal(int n) //n为边的数量 { int sum = 0; make_set(); for(int i = 0; i < n; i ++){ //从权最小的边开始加进图中 if(find_set(edge[i].start) != find_set(edge[i].end)){ Union(edge[i].start, edge[i].end); sum += edge[i].val; } } return sum; }int main(){ while(scanf("%d", &n),n){ //读入部分 char x, y; int m, weight; int cnt = 0; for(int i = 0; i < n - 1; i ++){ cin >> x >> m; for(int j = 0; j < m; j ++){ cin >> y >> weight; edge[cnt].start = x - 'A'; edge[cnt].end = y - 'A'; edge[cnt].val = weight; cnt ++; } } //算法实现部分 sort(edge, edge + cnt, cmp); //对边按权从小到大排序 cout << kruskal(cnt) << endl; } }
0 0
- Kruskal算法简明
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- kruskal算法
- kruskal算法
- Kruskal算法
- kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- Redis配置文件参考手册
- mysql 实现DENSE_RANK
- 小程序的view层
- 用css写的那些特色边框
- 简单实用的网站导航模块-带搜索功能的网站收藏夹-php-使用sqlite数据库-安装简单
- Kruskal算法简明
- 打印某一区间的素数(质数)
- Java编程的内存机制
- linux服务器重启服务命令步骤
- android修改默认的打包签名
- ARM基础学习-局部标号
- activity基础(Activity Task)
- docker
- linux,安装并配置PHP环境