结构体包含存放顶点,理解矩阵等重写prim算法求最小生成树
时间: 2023-08-06 19:15:55 浏览: 89
在 Prim 算法中,我们需要存储图的边信息以及每个节点是否已经被加入集合中。一个常见的做法是使用邻接表和一个 bool 数组来实现。但是,我们也可以使用结构体来存储图的信息,这样代码的可读性和可维护性会更好。
假设我们有一个无向图,其中每个节点都有一个编号,编号从 1 到 n,边的权值用一个矩阵 `graph` 存储。现在我们要使用 Prim 算法求解这个图的最小生成树,我们可以使用如下的结构体:
```cpp
struct Edge {
int u; // 起点
int v; // 终点
int w; // 权值
Edge(int uu, int vv, int ww) : u(uu), v(vv), w(ww) {}
};
struct Graph {
int n; // 节点个数
vector<Edge> edges; // 图中的所有边
vector<vector<int>> matrix; // 图的邻接矩阵
Graph(int nn) : n(nn) {
matrix.resize(n + 1, vector<int>(n + 1, 0));
}
void addEdge(int u, int v, int w) {
edges.push_back(Edge(u, v, w));
matrix[u][v] = matrix[v][u] = w;
}
};
```
其中,`Edge` 结构体表示一条边,包含起点、终点和权值。`Graph` 结构体表示一个图,包含节点个数、图中的所有边和图的邻接矩阵。在 `Graph` 结构体中,我们使用 `addEdge` 函数来添加一条边,它会将这条边加入 `edges` 数组中并更新邻接矩阵。
使用上面的结构体,我们可以重写 Prim 算法,代码如下:
```cpp
int prim(Graph& g, int start) {
int res = 0;
vector<bool> visited(g.n + 1, false);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
visited[start] = true;
for (int i = 1; i <= g.n; i++) {
if (i != start) {
pq.push({ g.matrix[start][i], i });
}
}
while (!pq.empty()) {
auto [w, u] = pq.top();
pq.pop();
if (visited[u]) continue;
visited[u] = true;
res += w;
for (int v = 1; v <= g.n; v++) {
if (!visited[v] && g.matrix[u][v] > 0) {
pq.push({ g.matrix[u][v], v });
}
}
}
return res;
}
```
在这个版本的 Prim 算法中,我们使用了 `Graph` 结构体来存储图的信息,而不是使用邻接表和 bool 数组。在实现时,我们首先将起点加入集合,然后将所有与起点相邻的点加入小根堆。在取出堆顶元素时,我们只需要遍历与它相邻的点,而不需要遍历所有的节点。最后返回最小生成树的总权值即可。
使用结构体来存储图的信息,可以让代码更加简洁易懂,而且更加符合面向对象的设计思想。
阅读全文