最小生成树--Prim--C++

//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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值