最小生成树算法-Kruskal算法
in Algorithm Pageviews
最小生成树: 给定一张边带权的无向图 G = (V,E),其中 V 表示图中点的集合,E 表示图中边的集合,**n = | V | ,m = | E | 。由 **V 中的全部 n 个顶点和 E 中 n − 1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。 |
克鲁斯卡尔(Kruskal)算法
题目举例:
给定n个顶点m条边的无向图,图中可能有重边和自环,边权可能为负数,求该图最小生成树的边的权重之和。
class Solutin{
public:
// 并查集
int find(int x)
{
if (x != p[x]) {
p[x] = find(p[x]);
}
return p[x];
}
int kruskal(vector<tuple<int, int, int>> &edges, int n)
{
p.resize(2 * edges.size());
// 按照权值升序排序
std::sort(edges.begin(), edges.end(), [](const tuple<int, int, int> &a, const tuple<int, int, int> &b){
return std::get<2>(a) < std::get<2>(b);
});
std::generate(p.begin(), p.end(), [i = 0]() mutable {return i++;});
int res = 0;
int cnt = 0;
for (int i = 0; i < edges.size(); i++) {
auto [a, b, w] = edges[i];
a = find(a);
b = find(b);
if (a != b) {
p[a] = b;
res += w;
cnt++;
}
}
return cnt < n - 1 ? INT_MIN : res;
}
vector<int> p;
};