最小生成树-普林算法(Prim)/克鲁斯卡尔算法(Kruskal)
2014-12-04 14:17
1341 查看
问题提出:
一个公司计划建立一个通信网络来连接它的一个计算机中心。可以用租用的电话线连接这些中心的任何一对。应当妊娠瘙痒哪些连接,以便保证在任何两个计算机中心之间都有通路,且网络的总成本最小?可以用下较长所示的带权图为这个问题建模,其中顶点表示计算机中心,边表示可能租用的电话线,边上的权是边所表示的电话线的月租费。通过找出一棵生成树,使得这棵树的各边的权之和为最小,就可以解决这个问题。这样的生成树称为最小生成树。最小生成树定义:
在一个具有V个节点的连通无向图中,找到一个子图,该子图包含原图的所有节点和部分连接边,且不能形成回路,同时子图边的权值总和最小。
最小生成树的算法:
根据对安全边的不同规则,有两种算法可以生成最小生成树。即Kruskal算法和Prim算法。
1.普林算法(Prim)
该算法所具有的一个性质是集合A中的边总是构成一棵树,而不是森林。这棵树从任意一个根节点开始,一直长大到覆盖V中所有的节点为止。算法每一步在链接集合A和A之外的节点的边,选择一条轻量级边加入到集合A中。步骤:
设是带权值的连通图,A是上最小生成树中边的集合:
(1)初始令,(), A=NULL
(2)在所有,的边中,找一条权值最小的边
(3)将并入集合A,同时并入
(4)重复上述操作直至为止,则为的最小生成树
判断规则:在所有,的边中,找一条权值最小的边,连接该边,但不能形成回路;
举例:
该图为原始图
第一步:选取一个初始节点a为根节点,并找到权值为最小的边,即为ab;
第二步:在所有,的边中,找一条权值最小的边;即权值最小边为bc或者ah;这里选取bc
第三步:在所有,的边中,找一条权值最小的边;即选择ci;
第四步:在所有,的边中,找一条权值最小的边;即选择cf;
第五步:在所有,的边中,找一条权值最小的边;即选择fg;
第六步:在所有,的边中,找一条权值最小的边;即选择gh;
第七步:在所有,的边中,找一条权值最小的边;必须保证不能形成回路,即选择cd;
最后一步:在所有,的边中,找一条权值最小的边;必须保证不能形成回路,即选择de;由于树包含了所有节点,且满足,则在此终止,为的最小生成树。
很简单的地说,就是建立一棵树T,和不在树中的顶点集合L,找出两者之间最短的距离的点,加入到树中,直到所有点加进去为止。
//d为图的邻近矩阵,p为所生成树的邻近矩阵, //n为图中点的个数 void Prim(int **d,int **p,int n) { int i,j,tmp,iT,iL; vector<int> T,L;//T是要生成的树,L为还没生成树的顶点 for(i=0;i<n;i++) L.push_back(i);//给L赋初始 while(L.size()){//当L为空时,即已经生成树完毕 tmp=d[0][0];iT=iL=0;//以第一个点作为初始点 for(i=0;i<T.size();i++){//找出树与非树顶点之间距离最小的点,并记录 for(j=L.size()-1;j>=0;j--){ if(tmp>=d[T[i]][L[j]]){ tmp=d[T[i]][L[j]]; iT=i;iL=j; } } } cout<<L[iL]<<" "; T.push_back(L[iL]);//将找到的点添加到树中 p[T[iT]][L[iL]]=1; L.erase(L.begin()+iL);//且从剩余的点中删除 } cout<<endl; }
时间复杂度:
最小边、权的数据结构 | 时间复杂度(总计) |
---|---|
邻接矩阵、搜索 | O(V2) |
二叉堆、邻接表 | O((V + E) log(V)) = O(E log(V)) |
斐波那契堆、邻接表 | O(E + V log(V)) |
2.克鲁斯卡尔算法(Kruskal)
3.网络资源
http://blog.csdn.net/chenhanzhun/article/details/39006205http://blog.csdn.net/niushuai666/article/details/6689285 http://baike.baidu.com/view/247951.htm?fr=aladdin
相关文章推荐
- 数据结构与算法之最小生成树-普林算法(Prim)/克鲁斯卡尔算法(Kruskal)
- 算法复习 - 最小生成树算法 Prim、Kruskal(普里姆算法、 克鲁斯卡尔算法)
- hdu1233还是畅通工程 最小生成树(prim或kruskal)
- 最小生成树求法 Prim + Kruskal
- 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
- HDU1102 最小生成树(已构造好部分边)Prim与Kruskal
- c++ 最小生成树——Prim和Kruskal理解与分析
- 最小生成树的两种算法图解(Kruskal与prim)
- poj1861 最小生成树 prim & kruskal
- 图的最小生成树(Prim、Kruskal)
- 最小生成树prim和kruskal
- 图论算法(四)--最小生成树的Kruskal [ 加边 ] 、Prim [ 加点 ] 的解法(JAVA)
- ZOJ 2048 Highways 最小生成树 Kruskal && Prim
- 最小生成树两个重要的算法:Prim 和 Kruskal
- 最小生成树(prim和kruskal)
- 2017-07-18:最小生成树(Prim&&Kruskal)
- HDOJ 1233 还是畅通工程 最小生成树 kruskal && prim
- HDOJ 1301 Jungle Roads 最小生成树 kruskal && prim
- 贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)
- 最小生成树 prim 算法 与kruskal 算法