最小生成树:包含图中全部顶点的极小联通子图。
极小:因为要取全部顶点,所以边要取最少,n个结点最少有n-1条边。边多了可能会导致回路,边少了会不连通。
Prime算法:加点法
假设顶点集V={v0,v1,v2,v3,v4},U是空集
(1)从顶点集V中任意选取一个顶点放入U,假设选取v0
则U={v0},V-U={v1 , v2 , v3 , v4 , v5 }
cost={(v0 , v1)34,(v0 , v2)46,(v0, v3)∞,(v0 , v4)∞,(v0, v5 )19}
(2) 第一次迭代:
U={v0 , v5 },V-U={v1 , v2 , v3 , v4}
cost={(v0 , v1)34,(v5 , v2)25,(v5, v3)25,(v5 , v4)26}
(3)第二次迭代:
U={v0 , v5 , v2 },V-U={v1 , v3 , v4 }
cost ={(v0 , v1)34, (v2, v3)17, (v5 , v4)26}
此时要找v1到U中顶点的最小权值,只需比较(v0,v1)25和(v2,v1)∞
此时要找v3到U中顶点的最小权值,只需比较(v5,v3)25和(v2,v3)17
此时要找v4到U中顶点的最小权值,只需比较(v5,v4)25和(v2,v4)∞
(4)第三次迭代:
U={v0 , v5, v2 , v3 },V-U={v1 , v4}
cost={(v0 , v1)34,(v5 , v4)26}
(5)第四次迭代:
U={v0 , v5, v2 , v3 , v4 },V-U={v1 }
cost ={(v4 , v1)12}
最终结果:
#include <iostream>
using namespace std;
class MGraph{
public:
MGraph(char a[],int n,int e);
void Prim(int v);
private:
char vertex[100];//存放图中顶点
int edge[100][100];//存放图中边
int vertexNum,edgeNum;
int MinEdge(int r[],int n);
};
MGraph::MGraph(char a[],int n,int e){
int i,j,k,w;
vertexNum=n;
edgeNum=e;
for(i=0;i<vertexNum;i++)//存储顶点
vertex[i]=a[i];
for(i=0;i<vertexNum;i++){//初始化邻接矩阵
for(j=0;j<vertexNum;j++){
if(i==j)
edge[i][j]==0;
else
edge[i][j]=100;//假设边上的权值最大是100
}
}
for(k=0;k<edgeNum;k++){
cout<<"请输入边两个顶点的编号和边上的权值:"<<endl;
cin>>i>>j>>w;
edge[i][j]=w;
edge[j][i]=w;
}
}
void MGraph::Prim(int v){//从顶点v出发
int i,j,k;
int adjvex[100];//候选最短边的邻接点
int lowcost[100];//候选最短边的权值
lowcost[v]=0;//把顶点v加入集合U
for(i=0;i<vertexNum;i++){
lowcost[i]=edge[v][i];
adjvex[i]=v;
}
for(k=1;k<vertexNum;k++){//迭代n-1次
j=MinEdge(lowcost,vertexNum);//找出每次V-U到U的最小权值对应的j
cout<<j<<" "<<adjvex[j]<<" "<<lowcost[j]<<endl;
lowcost[j]=0;//把顶点j加入U
for(i=0;i<vertexNum;i++){
if(edge[i][j]<lowcost[i]){
lowcost[i]=edge[i][j];
adjvex[i]=j;
}
}
}
}
int MGraph::MinEdge(int r[],int n){
int i,index=0;
int min=100;//假设边上的权值最大是100
for(i=1;i<n;i++){
if(r[i]!=0&&r[i]<min){
min=r[i];
index=i;
}
}
return index;
}
int main( )
{
char ch[6]={'A','B','C','D','E','F'};
MGraph mg(ch,6,9);
mg.Prim(0);
return 0;
}
运行结果
请输入边两个顶点的编号和边上的权值:
0 1 34
请输入边两个顶点的编号和边上的权值:
0 2 46
请输入边两个顶点的编号和边上的权值:
0 5 19
请输入边两个顶点的编号和边上的权值:
1 4 12
请输入边两个顶点的编号和边上的权值:
2 3 17
请输入边两个顶点的编号和边上的权值:
2 5 25
请输入边两个顶点的编号和边上的权值:
3 4 38
请输入边两个顶点的编号和边上的权值:
3 5 25
请输入边两个顶点的编号和边上的权值:
4 5 26
5 0 19
2 5 25
3 2 17
4 5 26
1 4 12