、
//PRIM.h
#ifndef PRIM_H
#define PRIM_H
struct Ass{
int value;
int index;//储存已经选好的点与数组下标的边是最小的
};
class MGraph{
public:
int Vex;
int **value;
MGraph(int n=0);
bool Inition();
};
class PRIM{
public:
int MiniSpanTree_PRIM(const MGraph& G, int n);
};
#endif
//PRIM.cpp
#include"PRIM.h"
#include<iostream>
using namespace std;
#define MAX_VALUE 100
MGraph::MGraph(int n){
Vex = n;
value = new int*[Vex]();
for (int i = 0; i < Vex; i++){
value[i] = new int[Vex]();//value都是0
}
}
bool MGraph::Inition(){
if (!value) return false;
int a, b, cost,min,max;
for (int i = 0; i<Vex; i++){
for (int j = i + 1; j<Vex; j++){//用上三角矩阵存储
value[i][j] = MAX_VALUE;
}
}
while (cin >> a&&a){
cin >> b >> cost;
min = a>b ? b : a;
max = a > b ? a : b;
value[min-1][max-1] = cost;//注意-1,因为输入的时候从1开始
}
/*for (int i = 0; i < Vex; i++){
for (int j = i + 1; j < Vex; j++){
cout << value[i][j] << " ";
}
cout << endl;
}*/
return true;
}
int PRIM:: MiniSpanTree_PRIM(const MGraph& G, int n){
int sum = 0;//计算权值
//这里G用const会避免改变原来值大小,也可以不用写复制构造函数了,因为MGraph中有指针,所以要深复制
//从第n个顶点出发,构造网G的最小生成树,输出T的各条边
Ass* closedge = new Ass[G.Vex]();//辅助数组,记录每个顶点的边最小值
for (int i = 0; i < G.Vex; i++){
closedge[i].value = MAX_VALUE;//初始化辅助数组
closedge[i].index = n;
}
for (int i = 0; i < G.Vex - 1; i++){
//循环G.Vex-1次,选G.Vex-1条边
//update closedge
closedge[n].value = 0;//表示该顶点已经选好了
for (int i = 0; i < G.Vex; i++){
if (i != n){
int min, max;
min = n>i ? i : n;
max = n>i ? n : i;
if (G.value[min][max] < closedge[i].value && (closedge[i].value)){
closedge[i].index = n;
closedge[i].value = G.value[min][max];
}
}
}
//选边、点
int min, u, j;
for (j = 0, min = MAX_VALUE; j < G.Vex; j++){
if ((min>closedge[j].value) && (closedge[j].value)){
min = closedge[j].value;
n = j;
u = closedge[j].index;
}
}
cout << "lowcost:" << min << '\t' << u + 1 << "->" << n + 1<<endl;
sum += min;
}
return sum;
}
//main.cpp
#include<iostream>
#include"PRIM.h"
using namespace std;
int main(){
int n;
cin >> n;
MGraph g(n);
g.Inition();
PRIM a;
cout << "Please input the point number you want to begain with:"<<endl;
cin >> n;
cout<<"min_sum="<<a.MiniSpanTree_PRIM(g,n-1)<<endl;//从0开始计数,即第二个参数值从0开始
system("pause");
return 0;
}