7.4.3 最小生成树

最小生成树

参考书:《数据结构(C语言版)》严蔚敏

正在学习这本书,把书中的数据结构用 c++ 代码实现了一遍

prim 算法

时间复杂度 \(O(n^2)\), 是顶点数的平方,和边数无关。适合与求边稠密的网的最小生成树

#include <vector>
#include <cstdio>
#include <climits>

using namespace std;

unsigned minimum(const vector<pair<unsigned, int>>& closedge) {
    unsigned res = 0;
    int lowcost = INT_MAX;
    for (unsigned i = 0; i < closedge.size(); ++i) {
        if (closedge[i].second != 0 && closedge[i].second < lowcost) {
            res = i;
            lowcost = closedge[i].second;
        }
    }
    return res;
}

/*
 * 和书上相比做了一些化简:
 * 1. 直接用邻接矩阵表示图,没有用 struct MGraph
 * 2. 用 vector<pair<unsigned, int>> 表示 closedge
 */
void MinSpanTree_PRIM(const vector<vector<int>>& G, unsigned u) {
    unsigned vecnum = G.size();
    // closedge[i] 表示集合 U 一步到达 集合 V-U 中顶点 i 的最小cost;
    // pair<unsigned, int>: first 表示通过哪个顶点到达 i,second: 最小 cost 的值
    vector<pair<unsigned, int>> closedge(vecnum);
    for (unsigned i = 0; i < vecnum; ++i) {
            closedge[i] = {u, G[u][i]};
    }

    printf("first vec is V%u\n", u + 1);
    for (unsigned i = 1; i < vecnum; ++i) {
        unsigned k = minimum(closedge);
        printf("next vec is V%u, cost: %d\n", k + 1, closedge[k].second);
        closedge[k].second = 0; // 点 k 加入集合 U

        for (unsigned j = 0; j < vecnum; ++j) {
            if (G[k][j] < closedge[j].second)
                closedge[j] = {k, G[k][j]}; // 更新 U 到 集合 V-U 中顶点的最小 cost
        }
    }
}

int main() {
    vector<vector<int>> Graph = {
      //           v1,        v2,      v3,    v4,      v5,        v6
      /*  v1  */  {0,         6,       1,     5,       INT_MAX,   INT_MAX},
      /*  v2  */  {6,         0,       5,     INT_MAX, 3,         INT_MAX},
      /*  v3  */  {1,         5,       0,     5,       6,         4},
      /*  v4  */  {5,         INT_MAX, 5,     0,       INT_MAX,   2},
      /*  v5  */  {INT_MAX,   3,       6,     INT_MAX, 0,         6},
      /*  v6  */  {INT_MAX,   INT_MAX, 4,     2,       6,         0}
    };

    MinSpanTree_PRIM(Graph, 0);
    return 0;
}

img

kruskal 算法

时间复杂度 \(O(eloge)\),e 为网中边的数目。适合求边稀疏的网的最小生成树

posted @ 2024-06-18 14:46  卑以自牧lq  阅读(2)  评论(0编辑  收藏  举报