Prim算法求最小生成树

来源:互联网 发布:演唱会灯光编程 编辑:程序博客网 时间:2024/04/28 02:05
#include <iostream>#include <climits> /* for INT_MAX */using namespace std;/** 顶点数最大值. */const int MAX_NV = 100;/** 边的权值类型,可以为int, float, double. */typedef int graph_weight_t;const graph_weight_t GRAPH_INF = INT_MAX;/*** @struct 图,用邻接矩阵(Adjacency Matrix).*/struct graph_t {    int nv; // 顶点数    int ne; // 边数    // 邻接矩阵,存放边的信息,如权重等    graph_weight_t matrix[MAX_NV][MAX_NV];};graph_t g;struct closedge_t {    int adjvex; /* 弧尾,属于U,注:弧尾是弧的起点,弧头是弧的终点,因为终点带有箭头,所以叫弧头 */    /* 边adjvex-> 本下标的权值,-GRAPH_INF 表示已经加入U */    graph_weight_t lowcost;};/** @brief 在V-E 集合中寻找最小的边* @param[in] closedge MST 中的边,起点为adjvex,终点为本下标* @param[in] n closedge 数组的长度* @return 找到了则返回弧头的下标,V-U 为空集则返回-1,表示终止*/static int min_element(const closedge_t closedge[], int n) {    int min_value = GRAPH_INF;    int min_pos = -1;    for (int i = 0; i < n; i++)        if (closedge[i].lowcost > -GRAPH_INF) {            if (min_value > closedge[i].lowcost) {                min_value = closedge[i].lowcost;                min_pos = i;            }        }        return min_pos;}/*** @brief Prim 算法,求图的最小生成树.* @param[in] g 图对象的指针* @return MST 的边的权值之和*/graph_weight_t prim(const graph_t &g) {    graph_weight_t sum = 0; /* 权值之和*/    int u = 0; /* 从0 号顶点出发*/    const int n = g.nv;    /* closedge[n],记录从顶点集U 到V-U 的边*/    closedge_t* const closedge = new closedge_t[n];    /* 辅助数组初始化*/    for (int i = 0; i < n; i++) if (i != u) {        closedge[i].adjvex = u;        closedge[i].lowcost = g.matrix[u][i];    }    closedge[u].lowcost = -GRAPH_INF; /* 初始, U={u} */    for (int i = 0; i < n; i++) if (i != u) { /* 其余的n-1 个顶点*/        /* 求出TE 的下一个顶点k */        const int k = min_element(closedge, n);        /* 输出此边closedge[k].adjvex --> k */        cout << (char)('A' + closedge[k].adjvex) << " - " << (char)('A' + k)            << " : "<< g.matrix[closedge[k].adjvex][k] << endl;        sum += g.matrix[closedge[k].adjvex][k];        // sum += closedge[k].lowcost; // 等价        closedge[k].lowcost = -GRAPH_INF; /* 顶点k 并入U,表示此边加入TE */        /* 更新k 的邻接点的值,不相邻为无穷大*/        for (int j = 0; j < n; j++) {            const graph_weight_t w = g.matrix[k][j];            if (w < closedge[j].lowcost) {                closedge[j].adjvex = k;                closedge[j].lowcost = w;            }        }    }    delete[] closedge;    return sum;}/** 读取输入,构建图. */void read_graph() {    int m, n;    /* 读取节点和边的数目*/    cin >> m >> n;    g.nv = m;    g.ne = n;    /* 初始化图,所有节点间距离为无穷大*/    for (int i = 0; i < m; i++) {        for (int j = 0; j < m; j++) {            g.matrix[i][j] = GRAPH_INF;        }    }    /* 读取边信息*/    for (int k = 0; k < n; k++) {        char chx, chy;        int w;        cin >> chx >> chy >> w;        const int i = chx - 'A';        const int j = chy - 'A';        g.matrix[i][j] = w;        g.matrix[j][i] = w;    }}int main() {    read_graph();    cout << "Total : " << prim(g) << endl;    return 0;}/* test输入数据:7 11A B 7A D 5B C 8B D 9B E 7C E 5D E 15D F 6E F 8E G 9F G 11输出:A - D : 5D - F : 6A - B : 7B - E : 7E - C : 5E - G : 9Total:39*/

0 0
原创粉丝点击