最小生成树算法prim and kruskal
2014-04-26 16:50
429 查看
一.最小生成树定义:
从不同顶点出发或搜索次序不同,可得到不同的生成树
生成树的权:对连通网络来说,边附上权,生成树也带权,我们把生成树各边的权值总和称为生成树的权
最小代价生成树:在一个连通网的所有生成树中, 各边的代价之和最小的那棵生成树称为该连通网的最小代价生成树(Minimum Cost Spanning Tree),简称为最小生成树(MST)。
二.最小生成树prim算法
算法思路:step1:假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于V),TE={}开始。
step2:在所有的u属于U,v属于V-U的边(u,v)属于E中找一条代价最小的边(u0,v0)并入集合TE。同时v0并入U。
step3:更新边(u,v)的最小值。
step4:c重复step2 and step3直到U=V。
code:
三.最小生成树kruskal算法
算法思路:step1:假设联通网N=(V,{E}),则领最小生成树的初始状态为只有n个定点而无边的非联通图T=(V,{}),同中每个定点自成一个连通分量。
step2:在E中选择代价最小的边,若改边的定点落在T中不同的连通分量上,则将此边加入到T中,否则舍弃此边而选择下一条代价最小的边。
step3:依次类推知道T中所有定点都在同一连通分量上。
时间复杂度:O(eloge)
从不同顶点出发或搜索次序不同,可得到不同的生成树
生成树的权:对连通网络来说,边附上权,生成树也带权,我们把生成树各边的权值总和称为生成树的权
最小代价生成树:在一个连通网的所有生成树中, 各边的代价之和最小的那棵生成树称为该连通网的最小代价生成树(Minimum Cost Spanning Tree),简称为最小生成树(MST)。
二.最小生成树prim算法
算法思路:step1:假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于V),TE={}开始。
step2:在所有的u属于U,v属于V-U的边(u,v)属于E中找一条代价最小的边(u0,v0)并入集合TE。同时v0并入U。
step3:更新边(u,v)的最小值。
step4:c重复step2 and step3直到U=V。
code:
//MiniSpanTree_Prim.cpp //This function is to create MiniSpanTree_Prim with Prim Algorithm # include <iostream.h> # include <malloc.h> # include <conio.h> # define INFINITY 1000 # define MAX_VERTEX_NUM 20 # define OK 1 typedef enum{DG,DN,UDG,UDN} GraphKind; typedef int EType; typedef int InfoType; typedef int VertexType; typedef int VRType; typedef int lowcost; typedef struct //define Closedege structure { VertexType adjvex; VRType lowcost; }Closedge; typedef struct ArcCell //define MGraph structure { EType adj; InfoType *info; }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { VertexType vexs[MAX_VERTEX_NUM]; AdjMatrix arcs; int vexnum,arcnum; GraphKind kind; }MGraph; int CreatUDN(MGraph &G) //CreatUDN() sub-function { int IncInfo,i=0,j=0,k,v1,v2,w; cout<<endl<<"Please input the number of G.vexnum (eg,G.vexnum=4) : "; cin>>G.vexnum; //input the number of vex cout<<"Please input the number of G.arcnum (eg,G.arcnum=4) : "; cin>>G.arcnum; //input the number of arc for(i=0;i<G.vexnum;++i) for(j=i;j<G.vexnum;++j) { G.arcs[i][j].adj=G.arcs[j][i].adj=INFINITY; //initial weigh G.arcs[i][j].info=G.arcs[j][i].info=NULL; } cout<<"Please input IncInfo (0 for none) : "; cin>>IncInfo; //if need information, input non-zero cout<<"Plese input arc(V1-->V2), For example: (V1=1,V2=3),(V1=2,V2=4)..."<<endl; for(k=0;k<G.arcnum;++k) //input arc(v1,v2) { cout<<endl<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : "; cin>>v1; cout<<"Please input the "<<k+1<<"th arc's v2 (0<v2<G.vexnum) : "; cin>>v2; cout<<"Please input the "<<k+1<<"th arc's weight : "; cin>>w; i=v1; j=v2; while(i<1||i>G.vexnum||j<1||j>G.vexnum) //if (v1,v2) illegal { cout<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : "; cin>>v1; cout<<"Please input the "<<k+1<<"th arc's v2 (0<v1<G.vexnum) : "; cin>>v2; cout<<"Please input the "<<k+1<<"th arc's weight : "; cin>>w; i=v1; j=v2; } //while end i--; j--; G.arcs[i][j].adj=G.arcs[j][i].adj=w; // cout<<"G.arcs["<<i+1<<"]["<<j+1<<"].adj="; cout<<"G.arcs["<<j+1<<"]["<<i+1<<"].adj="<<G.arcs[j][i].adj<<endl; if(IncInfo) { cout<<"Please input the "<<k+1<<"th arc's Info : "; cin>>*G.arcs[i][j].info; //input information } } //for end return (OK); } //CreatUDN() end int Minimum(Closedge *closedge,int Vexnum) //Minimum() sub-function { int min=1,j; //return min (closedge[min].lowcost) if(closedge[min].lowcost==0) min++; //closedge[min].lowcost!=0 for(j=0;j<Vexnum;++j) if(closedge[j].lowcost<closedge[min].lowcost &&closedge[j].lowcost>0) min=j; return (min); } //Minimim() end int LocatedVex(MGraph G,VertexType u) //LocatedVex() sub-fuction { return (u); } void MiniSpanTree_Prim(MGraph G,VertexType u) //MiniSpanTree_Prim() sub-function { int k,j,i,Vexnum=G.vexnum; k=LocatedVex(G,u); Closedge closedge[MAX_VERTEX_NUM]; for(j=0;j<G.vexnum;++j) //initial closedge[] if(j!=k) { closedge[j].adjvex=u; // (u,j) closedge[j].lowcost=G.arcs[k][j].adj; } closedge[k].lowcost=0; //U include k for(i=1;i<G.vexnum;++i) { k=Minimum(closedge,Vexnum); //select k=min(closedge[vi].lowcost) cout<<endl<<"("<<closedge[k].adjvex+1<<","<<k+1<<")"; cout<<"="<<G.arcs[closedge[k].adjvex][k].adj; closedge[k].lowcost=0; //U include k for(j=0;j<G.vexnum;++j) //renew closedge[k] if(G.arcs[k][j].adj<closedge[j].lowcost) { closedge[j].adjvex=k; closedge[j].lowcost=G.arcs[k][j].adj; } //if end } //for end } //Minimun() end void main() //main() function { MGraph G; VertexType u=0; cout<<endl<<endl<<"MiniSpanTree_Prim.cpp"; cout<<endl<<"====================="<<endl; CreatUDN(G); //call CreatUDN(G) function cout<<endl<<"The MiniSpanTree_Prim is created as follow order:"; MiniSpanTree_Prim(G,u); //call MiniSpanTree_Prim() function cout<<endl<<endl<<"...OK!..."; getch(); } //main() end
三.最小生成树kruskal算法
算法思路:step1:假设联通网N=(V,{E}),则领最小生成树的初始状态为只有n个定点而无边的非联通图T=(V,{}),同中每个定点自成一个连通分量。
step2:在E中选择代价最小的边,若改边的定点落在T中不同的连通分量上,则将此边加入到T中,否则舍弃此边而选择下一条代价最小的边。
step3:依次类推知道T中所有定点都在同一连通分量上。
时间复杂度:O(eloge)
#include<iostream> #include<vector> #include<map> using namespace std; class edge { public: edge(char a,char b,int wight):ma(a),mb(b),mwight(wight){} edge(const edge &other) { ma = other.ma; mb = other.mb; mwight = other.mwight; } edge & operator=(const edge & other) { ma = other.ma; mb = other.mb; mwight = other.mwight; return *this; } char getma() { return ma; } char getmb() { return mb; } private: char ma; char mb; int mwight; }; void kruskal(vector<edge> & edges,map<char,int> & vertexs,vector<edge> &myedge) { vector<edge>::iterator begin = edges.begin(); for (;begin != edges.end(); begin++) { int vera = vertexs[begin->getma()]; int verb = vertexs[begin->getmb()]; if ( vera != verb) { myedge.push_back(*begin); map<char,int>::iterator item = vertexs.begin(); for(;item != vertexs.end();item++) { if (item->second == vera) { item->second = verb; } } } } } void main() { char ch; int i; edge edges[] = { edge('a','c',1), edge('d','f',2), edge('b','e',3), edge('c','f',4), edge('a','d',5), edge('c','d',5), edge('c','b',5), edge('a','b',6), edge('c','e',6), edge('c','f',6) }; map<char,int> vertex; vector<edge> myedges(edges,edges+sizeof(edges)/sizeof(edge)),result; for( ch='a', i =0;i<6;ch++,i++) { vertex.insert(std::pair<char,int>(ch,i)); } kruskal(myedges,vertex,result); for (vector<edge>::iterator start = result.begin(); start != result.end(); start++) { cout<<start->getma()<<"--"<<start->getmb()<<" "<<endl; } }
相关文章推荐
- 【算法——04】最小生成树——Prim和Kruskal算法
- 构造最小生成树的 prim 算法
- 最小生成树算法——Prim和Kruskal算法的实现
- Prim最小生成树算法
- PAT 数据结构 06-图6. 公路村村通(30)Prim最小生成树算法
- Prim最小生成树算法
- 最小生成树的两种算法总结(克鲁斯塔尔,prim)
- 最小生成树Prim算法理解
- 最小生成树Prim算法理解
- 最小生成树(MST)----普里姆(Prim)算法与克鲁斯卡尔(Kruskal)算法
- 最小生成树Prim and Kruskal
- 最小生成树之Prim(普里姆)算法
- 最小生成树算法之Prim
- 牛客网NowCoder 2018年全国多校算法寒假训练营练习比赛(第四场)A.石油采集(dfs) B.道路建设(最小生成树prim) C.求交集(暴力) F.Call to your teacher(迪杰斯特拉乱用) H.老子的全排列呢(dfs)
- hdu1102 Constructing Roads (最小生成树 prim 算法)
- 最小生成树Prim算法理解
- 最小生成树算法之prim
- HDU-1233 还是畅通工程 (prim 算法求最小生成树)
- hdu 1162 Eddy's picture 最小生成树入门题 Prim+Kruskal两种算法AC
- 【算法】最小生成树之prim