上面写到了prim算法,细心的应该已经发现了,prim只能用于无向图的最小生成树,这是由于prim优先选择一边,而在出现相同权值时,选择靠"左"的点,在有向图中,可能是相等后靠“右”的点离目标点更近。照理来说,无向图最小生成树,若不出现上述情况,即不出现权值相等的边,最小生成树上的点,即是树上任意一点到根节点的最短路径,但最小生成树是所有权值和最小,即prim算法本身对于无向图是不存在任何问题的。Dijkstra算法用记录每个点的权值和来解决了这两个问题,即可用来生成有向图的最短路径,以下源码还是用邻接矩阵实现,邻接表实现更容易,只在prim算法上稍作修改即可
#include<iostream>
#define MAX_VERTEX 100
#define INFINITE 65535
using namespace std;
//array
struct Vertex{
char data;
int mark;
};
Vertex vertex_infos[MAX_VERTEX];
int matrix[MAX_VERTEX][MAX_VERTEX];
//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;
}
for(int i=0;i<MAX_VERTEX;i++){
vertex_infos[i].data=0;
vertex_infos[i].mark=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].data;
}
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].data==0){
break;
}
weight_array[i]=matrix[0][i];
}
for(int i=1;i<MAX_VERTEX;i++){
if(vertex_infos[i].data ==0){
break;
}
int k=0;
int min=INFINITE;
for(int j=1;j<MAX_VERTEX;j++){
if(!vertex_infos[j].mark&&weight_array[j]<min){
min=weight_array[j];
k=j;
}
}
vertex_infos[k].mark=1;
for(int j=1;j<MAX_VERTEX;j++){
if(!vertex_infos[j].mark&&matrix[k][j]+min<weight_array[j]){
weight_array[j]=min+matrix[k][j];
vertex_parent[j]=k;
}
}
}
for(int i=0;i<MAX_VERTEX;i++){
if(vertex_infos[i].data ==0){
break;
}
cout<<vertex_parent[i];
}
cout<<endl;
return 0;
}