📅  最后修改于: 2023-12-03 14:44:25.441000             🧑  作者: Mango
最小生成树(Minimum Spanning Tree, MST)是用于在一个加权无向连通图中构造一棵生成树,使树的所有边的权值之和最小的树。MST问题是一个经典的图论问题,在实际中有着广泛的应用。Prim算法和Kruskal算法是两种常用的MST算法,它们的实现思路和效率不同,下面我们来简单介绍一下它们的区别。
Prim算法也叫做贪心算法,它以一个节点为起点开始,每次找到离该节点最短的边所对应的点,并将该点加入MST中。然后以新加入的点为起点,重复以上过程直到构造成功。
Prim算法的时间复杂度是O(n^2),其中n表示节点个数。Prim算法的优点是对于稠密图表现较好,复杂度不会太高,同时它能够输出每个节点在MST中的父亲结点,非常适合在求最短路径时使用。
以下是Prim算法的C++代码。
const int INF = 0x3f3f3f3f;
int prim(int n, int **G, int start) {
int *D = new int[n];
bool *flag = new bool[n];
int sum = 0;
for (int i=0; i<n; i++) {
D[i] = INF;
flag[i] = false;
}
D[start] = 0;
for (int i=0; i<n; i++) {
int min_v = INF, u;
for (int j=0; j<n; j++) {
if (!flag[j] && D[j] < min_v) {
u = j;
min_v = D[j];
}
}
flag[u] = true;
sum += min_v;
for (int j=0; j<n; j++) {
if (!flag[j] && G[u][j] < D[j]) {
D[j] = G[u][j];
}
}
}
delete[] D;
delete[] flag;
return sum;
}
Kruskal算法也是贪心算法的一种,它的实现是将所有的边按照权值从小到大排序,依次取出最小权值的边,如果这条边连接的两个端点在同一集合内,则不需要加入最小生成树中,否则加入最小生成树中,直到选取n-1条边为止。
Kruskal算法的时间复杂度是O(m logm),其中m表示边的数量。Kruskal算法的优点是对于稀疏图表现较好,同时它不需要遍历所有的节点,只需要遍历所有的边,对于大规模的图表现更为优秀。
以下是Kruskal算法的C++代码。
const int MAX_N = 10000;
const int MAX_M = 100000;
struct Edge {
int u, v, w;
} edges[MAX_M];
int parent[MAX_N];
int rank[MAX_N];
void make_set() {
for (int i=0; i<MAX_N; i++) {
parent[i] = i;
rank[i] = 0;
}
}
int find_set(int x) {
if (parent[x] != x) {
parent[x] = find_set(parent[x]);
}
return parent[x];
}
void union_set(int x, int y) {
int px = find_set(x);
int py = find_set(y);
if (px == py) {
return;
}
if (rank[px] > rank[py]) {
parent[py] = px;
} else {
parent[px] = py;
if (rank[px] == rank[py]) {
rank[py]++;
}
}
}
bool cmp(Edge a, Edge b) {
return a.w < b.w;
}
int kruskal(int n, int m, Edge *edges) {
make_set();
sort(edges, edges+m, cmp);
int sum = 0, cnt = 0;
for (int i=0; i<m; i++) {
int u = edges[i].u;
int v = edges[i].v;
int w = edges[i].w;
if (find_set(u) == find_set(v)) {
continue;
}
union_set(u, v);
sum += w;
cnt++;
if (cnt == n-1) {
break;
}
}
return sum;
}
Prim算法与Kruskal算法都是MST算法的代表,它们在实现思路上略有不同,适用于不同类型的图。在实际应用中,根据具体的需求和数据特点,选择不同的MST算法可以使算法表现更加出色。