You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现最小生成树矩阵的展示?附相关C++代码片段

如何展示最小生成树(Minimum Spanning Tree)矩阵?

针对这个问题,我结合你提供的C++代码片段,整理了一套完整的实现方案——从补全Union-Find类,到生成MST邻接矩阵,再到美观地打印矩阵,一步步来:

1. 补全Union-Find不相交集合类

你给出的Union-Find代码片段不完整,这里补全结合路径压缩和按秩合并的完整实现,这两个启发式策略能让Union-Find的操作几乎达到常数时间复杂度:

#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include<iomanip>
using namespace std;

typedef pair<int, int> intPair;
typedef vector<double> doubleVector;
typedef vector<intPair> intPairVector;

// OOP风格的Union-Find实现,带路径压缩和按秩合并
class UnionFind {
private:
    vector<int> parent;
    vector<int> rank;
public:
    UnionFind(int n) {
        parent.resize(n);
        rank.resize(n, 0);
        // 初始化每个节点的父节点为自身
        for (int i = 0; i < n; ++i)
            parent[i] = i;
    }

    // 查找根节点,路径压缩优化
    int find(int x) {
        if (parent[x] != x)
            parent[x] = find(parent[x]);
        return parent[x];
    }

    // 按秩合并,避免树退化成链表
    bool unite(int x, int y) {
        int xr = find(x);
        int yr = find(y);
        if (xr == yr) return false; // 两个节点已在同一集合,无需合并
        if (rank[xr] < rank[yr])
            parent[xr] = yr;
        else {
            parent[yr] = xr;
            if (rank[xr] == rank[yr])
                rank[xr]++;
        }
        return true;
    }
};

2. 用Kruskal算法生成MST并构建邻接矩阵

我们用Kruskal算法来筛选出MST的边,然后把这些边映射到邻接矩阵中。这里先定义边的结构体,再实现构建矩阵的函数:

// 定义图的边,包含两个顶点和权重
struct Edge {
    int u, v;
    double weight;
    Edge(int u_, int v_, double w_) : u(u_), v(v_), weight(w_) {}
    // 重载小于运算符,用于按权重升序排序边(Kruskal算法需要)
    bool operator<(const Edge& other) const {
        return weight < other.weight;
    }
};

// 生成MST的邻接矩阵
vector<doubleVector> buildMSTMatrix(int numVertices, vector<Edge>& edges) {
    // 初始化MST矩阵,所有元素设为0(0表示两个顶点间无MST边)
    vector<doubleVector> mstMatrix(numVertices, doubleVector(numVertices, 0.0));
    UnionFind uf(numVertices);

    // 按边的权重从小到大排序
    sort(edges.begin(), edges.end());

    int edgesAdded = 0;
    for (Edge& e : edges) {
        // 如果两个顶点不在同一集合,就合并并加入MST
        if (uf.unite(e.u, e.v)) {
            // 无向图,所以双向赋值权重
            mstMatrix[e.u][e.v] = e.weight;
            mstMatrix[e.v][e.u] = e.weight;
            edgesAdded++;
            // MST的边数是顶点数-1,达到后提前退出循环
            if (edgesAdded == numVertices - 1)
                break;
        }
    }

    return mstMatrix;
}

3. 美观打印MST矩阵的函数

为了让矩阵看起来整齐易读,我们可以设置输出格式,固定小数位数并对齐每一列:

void printMatrix(const vector<doubleVector>& matrix) {
    int n = matrix.size();
    cout << "MST邻接矩阵:" << endl;
    // 设置输出格式:保留2位小数,每列宽度为8
    cout << fixed << setprecision(2);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << setw(8) << matrix[i][j];
        }
        cout << endl;
    }
}

4. 测试示例

我们用一个简单的4顶点图来测试整个流程:

int main() {
    int numVertices = 4;
    // 定义图的所有边(顶点编号从0开始)
    vector<Edge> edges = {
        Edge(0, 1, 1.0),
        Edge(0, 2, 3.0),
        Edge(1, 2, 1.0),
        Edge(1, 3, 5.0),
        Edge(2, 3, 2.0)
    };

    // 生成MST矩阵并打印
    vector<doubleVector> mstMatrix = buildMSTMatrix(numVertices, edges);
    printMatrix(mstMatrix);

    return 0;
}

运行结果

执行代码后,你会得到这样的输出:

MST邻接矩阵:
   0.00   1.00   0.00   0.00
   1.00   0.00   1.00   0.00
   0.00   1.00   0.00   2.00
   0.00   0.00   2.00   0.00

额外说明

  • 如果你的图是稠密图(顶点多、边也多),可以换成Prim算法(优先队列版本时间复杂度O(E log V))来实现,效率会更高。
  • 矩阵中的0值表示对应两个顶点在MST中没有直接相连的边,非0值就是MST边的权重。

内容的提问来源于stack exchange,提问作者Bailey Wells

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:47:25