Prim算法用于在加权连通图中搜索最小生成树,即搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。中心思想就是用1个数组存放父节点的index,以记录表示整个树形态,另外个数组用于存放权值,先将起始点对每个顶点权值写入,无连接用infinite表示,选出权值最小的点,并且在数组中将这个点置为0,然后用这个最小点到各点的权值比较数组中存放的权值,如果更小(0排除在外),则覆盖写入,并且存放父节点index,重复这个过程即可
代码实现:
#include<iostream>
#define MAX_VERTEX 100
#define INFINITE 65535
using namespace std;
//array
char vertex_infos[MAX_VERTEX];
int matrix[MAX_VERTEX][MAX_VERTEX];
//list
struct Side{
int index;
int weight;
Side* next;
};
struct Vertex{
char data;
Side* first;
};
typedef Vertex AdjList[MAX_VERTEX];
struct AdjGraph {
AdjList adjlist;
int num_vertex;
int num_side;
};
//common
int weight_array[MAX_VERTEX];
int vertex_parent[MAX_VERTEX];
int main(){
for(int i=0;i<MAX_VERTEX;i++){
vertex_parent[i]=0;
weight_array[i]=INFINITE;
}
//array
/*
for(int i=0;i<MAX_VERTEX;i++){
vertex_infos[i]=0;
for(int j=0;j<MAX_VERTEX;j++){
matrix[i][j]=INFINITE;
matrix[i][j]=INFINITE;
}
}
cout<<"input vertex and side nums:";
int num_vertex;
int num_side;
cin>>num_vertex>>num_side;
cout<<"input vertex char data:";
for(int i=0;i<num_vertex;i++){
cin>>vertex_infos[i];
}
for(int i=0;i<num_side;i++){
int v1;
int v2;
int weight;
cout<<"input two vertex:";
cin>>v1>>v2;
cout<<"input weight:";
cin>>weight;
matrix[v1][v2]=weight;
matrix[v2][v1]=weight;
}
//start from v0
for(int i=1;i<MAX_VERTEX;i++){
if(vertex_infos[i]==0){
break;
}
weight_array[i]=matrix[0][i];
}
for(int i=1;i<MAX_VERTEX;i++){
if(vertex_infos[i]==0){
break;
}
int k=0;
int min=INFINITE;
for(int j=1;j<MAX_VERTEX;j++){
if(weight_array[j]!=0&&weight_array[j]<min){
min=weight_array[j];
k=j;
}
}
weight_array[k]=0;
for(int j=1;j<MAX_VERTEX;j++){
if(weight_array[j]!=0&&matrix[k][j]<weight_array[j]){
weight_array[j]=matrix[k][j];
vertex_parent[j]=k;
}
}
}
for(int i=0;i<MAX_VERTEX;i++){
if(vertex_infos[i]==0){
break;
}
cout<<vertex_parent[i];
}
cout<<endl;*/
//list
AdjGraph adjGraph;
for(int i=0;i<MAX_VERTEX;i++){
adjGraph.adjlist[i].data=0;
adjGraph.adjlist[i].first=0;
}
cout<<"input vertex and side nums:";
cin>>adjGraph.num_vertex>>adjGraph.num_side;
cout<<"input vertex char data:";
for(int i=0;i<adjGraph.num_vertex;i++){
cin>>adjGraph.adjlist[i].data;
}
for(int i=0;i<adjGraph.num_side;i++){
int v1;
int v2;
int weight;
cout<<"input two vertex:";
cin>>v1>>v2;
cout<<"input weight:";
cin>>weight;
Side* side1=new Side();
side1->index=v2;
side1->weight=weight;
Side* side2=new Side();
side2->index=v1;
side2->weight=weight;
if(adjGraph.adjlist[v1].first==0){
adjGraph.adjlist[v1].first=side1;
}
else{
Side* temp=adjGraph.adjlist[v1].first;
adjGraph.adjlist[v1].first=side1;
side1->next=temp;
}
if(adjGraph.adjlist[v2].first==0){
adjGraph.adjlist[v2].first=side2;
}
else{
Side* temp=adjGraph.adjlist[v2].first;
adjGraph.adjlist[v2].first=side2;
side2->next=temp;
}
}
Side* p=adjGraph.adjlist[0].first;
while(p!=0){
if(p->weight<weight_array[p->index]){
weight_array[p->index]=p->weight;
}
p=p->next;
}
weight_array[0]=0;
for(int i=1;i<MAX_VERTEX;i++){
if(adjGraph.adjlist[i].data==0){
break;
}
int k=0;
int min=INFINITE;
for(int j=1;j<MAX_VERTEX;j++){
if(weight_array[j]!=0&&weight_array[j]<min){
min=weight_array[j];
k=j;
}
}
weight_array[k]=0;
p=adjGraph.adjlist[k].first;
while(p!=0){
if(p->weight<weight_array[p->index]){
weight_array[p->index]=p->weight;
vertex_parent[p->index]=k;
}
p=p->next;
}
}
for(int i=0;i<MAX_VERTEX;i++){
if(adjGraph.adjlist[i].data==0){
break;
}
cout<<vertex_parent[i];
}
cout<<endl;
return 0;
}