prim算法(选顶点)
不断选取最小权值的边并把对应的顶点不断并入的过程
过程:
1.随意选取起点:随意选择一个顶点作为起始点(不会影响结果),现在我们设U集合为当前所找到最小生成树里面的顶点,T集合为所找到的边。
2.在前一步的基础上寻找最小权值: 查找一个顶点在U={v1}集合中,另一个顶点在V-U集合中的最小权值
3.继续寻找最小权值:查找一个顶点在U={v1,v2}集合中,另一个顶点在V-U集合中的最小权值
4.每次都选取权值最小的边,但不能构成回路,构成环路的边则舍弃。遇到权值相等,又均不构成回路的边,随意选择哪一条,均不影响生成树结果
5.选取n-1条恰当的边以连通n个顶点
#include "iostream"
using namespace std;
#define MAXSIZE 10000
typedef struct
{
char vertex[100]; //顶点表
int arc[100][100]; //边表
int vertex_num; //顶点个数
int arc_num; //边的数目
}Agraph;
struct
{
char ver_vex; //顶点name
int low_weight; //权值
}edge[100];
int local_vertex(Agraph G,char v) //顶点位置信息
{
for (int i=0;i<G.vertex_num;i++)
{
if(G.vertex[i]==v)
{
return i;
}
}
return -1;
}
void creat_graph(Agraph &G) //构造图
{
int i,j ,k;
cout<<"输入图的顶点数,边数"<<endl;
cin>>G.vertex_num>>G.arc_num;
cout<<endl;
cout<<"输入顶点信息"<<endl;
for(i=0;i<G.vertex_num;i++)
{
cout<<"顶点name"<<(i+1)<<endl;
cin>>G.vertex[i];
}
cout<<endl;
for(i=0;i<G.vertex_num;i++)
{
for(j=0;j<G.vertex_num;j++)
{
G.arc[i][j]=MAXSIZE; //初始化邻接矩阵
}
}
for(k=0;k<G.arc_num;k++)
{
char v1,v2; //边所对应的两个顶点
int weight; //权值
cout<<"输入两个顶点name和边的权值"<<endl;
cin>>v1>>v2>>weight;
i= local_vertex(G,v1);
j= local_vertex(G,v2);
G.arc[i][j]=weight;
G.arc[j][i]=G.arc[i][j]; //生成邻接矩阵(给矩阵赋值)
}
}
int min(Agraph G)
{
int index=-1;
int min=MAXSIZE;
for(int i=0;i<G.vertex_num;i++)
{
if(edge[i].low_weight<min && edge[i].low_weight!=0)
{
min=edge[i].low_weight; //找到最小的边及位置
index=i;
}
}
return index;
}
//最小生成树prim算法
void prim(Agraph G,char u)
//每次都选取权值最小的边,
// 但不能构成回路,构成环路的边则舍弃。
// 遇到权值相等,又均不构成回路的边,
// 随意选择哪一条,均不影响生成树结果
{
int i,j,k;
char u0,v0;
k= local_vertex(G,u);
for(j=0;j<G.vertex_num;j++)
{
if(j!=k)
{
edge[j].ver_vex=u;
edge[j].low_weight=G.arc[k][j];
}
}
edge[k].low_weight=0;
for(i=1;i<G.vertex_num;i++)
{
k = min(G); //找出最短边,k是顶点index
u0 = edge[k].ver_vex; //找出所对应的顶点
v0 = G.vertex[k];
cout << u0 << "--->" << v0 << endl;
edge[k].low_weight = 0;
for (j = 0; j < G.vertex_num; j++) //更新数组
{
if (G.arc[k][j] < edge[j].low_weight)
{
edge[j].ver_vex = G.vertex[k];
edge[j].low_weight = G.arc[k][j];
}
}
}
}
int main()
{
Agraph G;
creat_graph(G);
cout<<endl;
for(int i=0;i<G.vertex_num;i++)
{
for(int j=0;j<G.vertex_num;j++)
{
if(G.arc[i][j]!=MAXSIZE)
{
cout<<G.arc[i][j]<<"\t";
}
else
{
cout<<"INF"<<"\t";
}
}
cout<<endl;
}
prim(G,'a');
}
input:
6 8
a
b
c
d
e
f
a b 1
b c 2
c d 3
d e 4
e a 5
c f 6
e f 7
a f 9