您的位置:首页 > 其它

最小生成树 kruskal算法简介

2014-05-04 21:40 281 查看
生成树——在一个图中的一个联通子图 使得所有的节点都被(访问)

最小生成树 (MST) 即联通子图的总代价(路程)最小

已知的一个图 有n个点 m条边

kruskal的算法如下

先对边从小到大排序

从最小的边起,不停的合并这条边的两个节点到一个集合,如果这条边的两个节点已经在一个集合里,则无视,否则形成回路(显然错误)直到所有的节点并到一个集合里

这里需要用到并查集来合并节点

int cmp(const int i,const int j) {
return w[i] < w[j];
}
int find(int x) {  //并查集的查找函数 得到x的根节点
return p[x] == x ? x : p[x] = find(p[x]);
}
int kruskal() {
int ans = 0;
for(int i = 0;i < n;i ++) p[i] = i;  //初始化根节点
for(int i = 0;i < t;i ++) r[i] = i;  //初始化r数组 代表边的编号
sort(r,r + t,cmp);  //根据w数组排r的序  一种间接排序思想  得到按照边的大小排序之后原来边的”编号“
for(int i = 0;i < t;i ++) {
int e = r[i];  //得到边的编号e
int x = find(u[e]);  //得到起点的根节点
int y = find(v[e]);  //得到终点的根节点
if(x != y) {  //如果两个节点不在一个集合
ans = max(ans,w[e]);
p[x] = y;  //合并两个集合
}
}
return ans;
}


这里并查集的find函数有一点技术含量 读者需要仔细体会

p[x] = find(p[x])


以上

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: