最小生成树算法:Prim、Kruskal
程序员文章站
2022-06-16 08:47:03
...
Prim算法实现完整代码:
#include<iostream>
using namespace std;
const int Max=100;
class MGraph{
public:
MGraph(){
}
MGraph(int n,int e);
~MGraph(){
}
public:
int arc[Max][Max];
int vertexNum,arcNum;
};
MGraph::MGraph(int n,int e){
int i,j;
vertexNum=n;
arcNum=e;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
arc[i][j]=10000;
for(int k=0;k<e;k++){
cin>>i>>j;//输入边的两个点下标及权值
cin>>arc[i][j];
arc[j][i]=arc[i][j];
}
}
class A{
public:
int lowcost;
int adjvex;
};
int MinEdge(A shortEdge[],int n){
int j;
int p=100001;
for(int i=1;i<n;i++)
for(int i=1;i<n;i++)
if(shortEdge[i].lowcost!=0&&shortEdge[i].lowcost<p){
p=shortEdge[i].lowcost;
j=i;
}
return j;
}
void Prim(MGraph G){
A shortEdge[Max];
for(int i=1;i<G.vertexNum;i++){
shortEdge[i].lowcost=G.arc[0][i];
shortEdge[i].adjvex=0;
}
shortEdge[0].lowcost=0;
for(int i=1;i<G.vertexNum;i++){
int k=0,j=0;
k=MinEdge(shortEdge,G.vertexNum);
cout<<"("<<shortEdge[k].adjvex<<","<<k<<") "<<shortEdge[k].lowcost<<endl;
shortEdge[k].lowcost=0;
for(j=1;j<G.vertexNum;j++){
if(shortEdge[j].lowcost!=0){
if(G.arc[k][j]<shortEdge[j].lowcost){
shortEdge[j].lowcost=G.arc[k][j];
shortEdge[j].adjvex=k;
}
}
}
}
int num=0;
for(int i=1;i<G.vertexNum;i++)
num+=G.arc[i][shortEdge[i].adjvex];
cout<<"最大的权值为:"<<num<<endl;
}
int main(){
int n,e;
cin>>n>>e;//输入顶点数、边数
MGraph G(n,e);
Prim(G);
return 0;
}
Kruskal算法的基本思想是以边为主导地位,始终都是选择当前可用的最小权值的边,步骤如下:
(1)设一个有n个顶点的连通网络为G(V,E),最初先构造一个只有n个顶点,没有边的非连通图T{V,Ø},图中每个顶点自成一个连通分量;
(2)当在E中选择一条具有最小权值的边时,若该边的两个顶点落在不同的连通分量上,则将此边加入到T中;否则,即这条边的两个顶点落在同一个连通分量上,则将此边舍去(此后永不选用这条边),重新选择一条权值最小的边;
(3)如此重复下去,直到所有顶点在同一个连通分量上为止。
Kruskal算法实现:
#include<iostream>
#include<algorithm>
using namespace std;
const int MaxVertex=10;
const int MaxEdge=100;
struct EdgeType{
public:
int from,to;
int weight;
};
bool cmp(struct EdgeType a,struct EdgeType b){
if(a.weight<b.weight){
return true;
}
return false;
}
class EdgeGraph{
public:
EdgeType edge[MaxEdge];
int vertexNum,edgeNum;
EdgeGraph(int vertexNum,int edgeNum);
};
EdgeGraph::EdgeGraph(int vertexNum,int edgeNum){
EdgeType edge1[edgeNum];
for(int i=0;i<edgeNum;i++)
cin>>edge1[i].from>>edge1[i].to>>edge1[i].weight;//输入边的两个点下标及权值
sort(edge1,edge1+edgeNum,cmp);
for(int i=0;i<edgeNum;i++)
edge[i]=edge1[i];
this->edgeNum=edgeNum;
this->vertexNum=vertexNum;
}
int FindRoot(int parent[],int v){
int t=v;
while(parent[t]!=-1)
t=parent[t];
return t;
}
void Kruskal(EdgeGraph G){
int parent[MaxVertex],vex1,vex2,num=0,sum=0;
for(int i=0;i<G.vertexNum;i++)
parent[i]=-1;
for(int i=0;i<G.edgeNum;i++){
vex1=FindRoot(parent,G.edge[i].from);
vex2=FindRoot(parent,G.edge[i].to);
if(vex1!=vex2){
parent[vex2]=vex1;
num++;
sum+=G.edge[i].weight;
if(num==(G.vertexNum-1))
break;
}
}
cout<<"最小的权值为:"<<sum<<endl;
}
int main(){
int vertexNum,edgeNum;
cin>>vertexNum>>edgeNum;//输入顶点数、边数
EdgeGraph G(vertexNum,edgeNum);
Kruskal(G);
return 0;
}
上面代码如有错误,欢迎大家指出!
上一篇: 图的连通性问题之最小生成树:Prim算法_Kruskal算法(
下一篇: JAVA编写发送126邮箱
推荐阅读
-
JS使用Prim算法和Kruskal算法实现最小生成树
-
最小生成树的java实现
-
洛谷 P3366 【模板】最小生成树
-
PHP树的深度编历生成迷宫及A*自动寻路算法实例分析
-
图论小结(一)包括一些最短路,最小生成树,差分约束,欧拉回路,的经典题和变种题。强连通,双连通,割点割桥的应用。二分匹配
-
数据结构(C实现)------- 最小生成树之Kruskal算法
-
python最小生成树kruskal与prim算法详解
-
洛谷P3366 【模板】最小生成树(Boruvka算法)
-
最小生成树两个经典算法(Prime算法、Kruskal算法) - biaobiao88
-
最小生成树的两种方法(Kruskal算法和Prim算法)