一.最小生成树定义:
二.最小生成树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:
1 //MiniSpanTree_Prim.cpp 2 //This function is to create MiniSpanTree_Prim with Prim Algorithm 3 # include <iostream.h> 4 # include <malloc.h> 5 # include <conio.h> 6 7 # define INFINITY 1000 8 # define MAX_VERTEX_NUM 20 9 # define OK 1 10 typedef enum{DG,DN,UDG,UDN} GraphKind; 11 typedef int EType; 12 typedef int InfoType; 13 typedef int VertexType; 14 typedef int VRType; 15 typedef int lowcost; 16 17 typedef struct //define Closedege structure 18 { VertexType adjvex; 19 VRType lowcost; 20 }Closedge; 21 22 typedef struct ArcCell //define MGraph structure 23 { EType adj; 24 InfoType *info; 25 }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 26 27 typedef struct 28 { VertexType vexs[MAX_VERTEX_NUM]; 29 AdjMatrix arcs; 30 int vexnum,arcnum; 31 GraphKind kind; 32 }MGraph; 33 34 int CreatUDN(MGraph &G) //CreatUDN() sub-function 35 { int IncInfo,i=0,j=0,k,v1,v2,w; 36 cout<<endl<<"Please input the number of G.vexnum (eg,G.vexnum=4) : "; 37 cin>>G.vexnum; //input the number of vex 38 cout<<"Please input the number of G.arcnum (eg,G.arcnum=4) : "; 39 cin>>G.arcnum; //input the number of arc 40 for(i=0;i<G.vexnum;++i) 41 for(j=i;j<G.vexnum;++j) 42 { G.arcs[i][j].adj=G.arcs[j][i].adj=INFINITY; //initial weigh 43 G.arcs[i][j].info=G.arcs[j][i].info=NULL; 44 } 45 cout<<"Please input IncInfo (0 for none) : "; 46 cin>>IncInfo; //if need information, input non-zero 47 cout<<"Plese input arc(V1-->V2), For example: (V1=1,V2=3),(V1=2,V2=4)..."<<endl; 48 for(k=0;k<G.arcnum;++k) //input arc(v1,v2) 49 { cout<<endl<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : "; 50 cin>>v1; 51 cout<<"Please input the "<<k+1<<"th arc's v2 (0<v2<G.vexnum) : "; 52 cin>>v2; 53 cout<<"Please input the "<<k+1<<"th arc's weight : "; 54 cin>>w; 55 i=v1; 56 j=v2; 57 while(i<1||i>G.vexnum||j<1||j>G.vexnum) //if (v1,v2) illegal 58 { cout<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : "; 59 cin>>v1; 60 cout<<"Please input the "<<k+1<<"th arc's v2 (0<v1<G.vexnum) : "; 61 cin>>v2; 62 cout<<"Please input the "<<k+1<<"th arc's weight : "; 63 cin>>w; 64 i=v1; 65 j=v2; 66 } //while end 67 i--; 68 j--; 69 G.arcs[i][j].adj=G.arcs[j][i].adj=w; // 70 cout<<"G.arcs["<<i+1<<"]["<<j+1<<"].adj="; 71 cout<<"G.arcs["<<j+1<<"]["<<i+1<<"].adj="<<G.arcs[j][i].adj<<endl; 72 if(IncInfo) 73 { cout<<"Please input the "<<k+1<<"th arc's Info : "; 74 cin>>*G.arcs[i][j].info; //input information 75 } 76 } //for end 77 return (OK); 78 } //CreatUDN() end 79 80 int Minimum(Closedge *closedge,int Vexnum) //Minimum() sub-function 81 { int min=1,j; //return min (closedge[min].lowcost) 82 if(closedge[min].lowcost==0) 83 min++; //closedge[min].lowcost!=0 84 for(j=0;j<Vexnum;++j) 85 if(closedge[j].lowcost<closedge[min].lowcost 86 &&closedge[j].lowcost>0) 87 min=j; 88 return (min); 89 } //Minimim() end 90 91 int LocatedVex(MGraph G,VertexType u) //LocatedVex() sub-fuction 92 { return (u); 93 } 94 95 void MiniSpanTree_Prim(MGraph G,VertexType u) //MiniSpanTree_Prim() sub-function 96 { int k,j,i,Vexnum=G.vexnum; 97 k=LocatedVex(G,u); 98 Closedge closedge[MAX_VERTEX_NUM]; 99 for(j=0;j<G.vexnum;++j) //initial closedge[] 100 if(j!=k) 101 { closedge[j].adjvex=u; // (u,j) 102 closedge[j].lowcost=G.arcs[k][j].adj; 103 } 104 closedge[k].lowcost=0; //U include k 105 for(i=1;i<G.vexnum;++i) 106 { k=Minimum(closedge,Vexnum); //select k=min(closedge[vi].lowcost) 107 cout<<endl<<"("<<closedge[k].adjvex+1<<","<<k+1<<")"; 108 cout<<"="<<G.arcs[closedge[k].adjvex][k].adj; 109 closedge[k].lowcost=0; //U include k 110 for(j=0;j<G.vexnum;++j) //renew closedge[k] 111 if(G.arcs[k][j].adj<closedge[j].lowcost) 112 { closedge[j].adjvex=k; 113 closedge[j].lowcost=G.arcs[k][j].adj; 114 } //if end 115 } //for end 116 } //Minimun() end 117 118 void main() //main() function 119 { MGraph G; 120 VertexType u=0; 121 cout<<endl<<endl<<"MiniSpanTree_Prim.cpp"; 122 cout<<endl<<"====================="<<endl; 123 CreatUDN(G); //call CreatUDN(G) function 124 cout<<endl<<"The MiniSpanTree_Prim is created as follow order:"; 125 MiniSpanTree_Prim(G,u); //call MiniSpanTree_Prim() function 126 cout<<endl<<endl<<"...OK!..."; 127 getch(); 128 } //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; } }