kruskal 算法b

来源:互联网 发布:西门子300编程演示 编辑:程序博客网 时间:2024/06/02 17:45

使用堆排序,并查集实现kruskal算法。

堆排序算法见:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

并查集合:http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html

#include "iostream"#include "vector"#include "fstream"using namespace std;struct edge{int u;int v;int weight;};std::vector<edge> E;//边的数组std::vector<int> rank;//秩,树的最大高度std::vector<int> father;//父亲节点int vertexnum;//节点数int edgenum;//边数void make_set(int x);// 初始化集合void swap(edge *a,edge *b);//交换边void initialvector(){// 初始化E.resize(edgenum);rank.resize(vertexnum,0);father.resize(vertexnum);for(int i = 0;i < vertexnum;i++){make_set(i);}}void getData(){//获取数据ifstream in("data");in>>vertexnum>>edgenum;initialvector();int from,to;double w;int i = 0;while(in>>from>>to>>w){E[i].u = from;E[i].v = to;E[i].weight = w;i++;}}void HeapAdjust(int i,int size){int lchild = 2*i + 1;//i的左孩子节点序号 int rchild = 2*i + 2;//i的右孩子节点序号 int min = i;if(i < size/2){//如果i是叶节点就不用进行调整if(lchild < size && E[lchild].weight < E[min].weight){min = lchild;}if(rchild < size && E[rchild].weight < E[min].weight){min = rchild;}if(min != i){swap(&E[i],&E[min]);HeapAdjust(min,size);//重新调整被破坏的堆}}}void swap(edge *a,edge *b){edge temp;temp = *a;*a = *b;*b = temp;}void make_heap(){for(int i = edgenum/2 -1;i>=0;i--){HeapAdjust(i,edgenum);}}edge minedge(int &m){swap(E[0],E[m]);HeapAdjust(0,--m);return E[m+1];}void make_set(int x){father[x] = x;}int find_set(int x){// 查找x元素所在的集合,回溯时压缩路径if(x != father[x]){father[x] = find_set(father[x]);}return father[x];}/*    按秩合并x,y所在的集合   下面的那个if else结构不是绝对的,具体根据情况变化   但是,宗旨是不变的即,按秩合并,实时更新秩。*/void unionset(int x,int y){x = find_set(x);y = find_set(y);if(x == y) return;if(rank[x] > rank[y]){father[y] = x ;}else{if(rank[x] == rank[y]){rank[y]++;}father[x] = y;}}int main(int argc, char const *argv[]){getData();  int u,v,i = 0;int m = edgenum - 1;std::vector<edge> minset;edge min_edge;make_heap();while(i < edgenum-1  && m > 0){min_edge = minedge(m);u = find_set(min_edge.u);v = find_set(min_edge.v);if(u != v){unionset(u,v);minset.push_back(min_edge);cout<<min_edge.u<<"->"<<min_edge.v<<"\t"<<min_edge.weight<<endl;i++;}}}
kruskal
data:

7 11
0 1 7
0 3 5
1 2 8
1 3 9
1 4 7
2 4 5
3 4 15
3 5 6
4 5 8
4 6 9
5 6 11

参考:http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html

http://www.slyar.com/blog/kruskal-disjoint-sets-c.html

http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

原创粉丝点击