无向图的最小连通分量——Kruskal算法
此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。
- 把图中的所有边按代价从小到大排序;
- 把图中的n个顶点看成独立的n棵树组成的森林;
- 按权值从小到大选择边,所选的边连接的两个顶点,应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。
- 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。
参考文章图解:什么是最小生成树?
vector<int> parents;
int count;
void init(int n){
count = n+1;
parents = vector<int>(n+1, 0);
for(int i=0; i<=n; ++i){
parents[i] = i;
}
}
int find(int x){
if(x != parents[x])
return find(parents[x]);
return parents[x];
}
void Union(int x, int y){
int rootX = find(x);
int rootY = find(y);
if(rootX == rootY)
return ;
parents[rootX] = rootY;
count--;
}
bool isConnected(int x, int y){
return find(x) == find(y);
}
/*
输入:
n, 节点数量
connections, {{a, b, w}} 无向图中的起点、终点、权重
*/
int minimumCost(int n, vector<vector<int>>& connections) {
sort(connections.begin(), connections.end(), [&](vector<int>& a, vector<int>& b){
return a[2] < b[2];
});
init(n);
int ans = 0;
for(int i=0; i<connections.size(); ++i){
int x,y,w;
x = connections[i][0];
y = connections[i][1];
w = connections[i][2];
if(! isConnected(x, y)){
Union(x, y);
ans += w;
}
}
return count == 2? ans : -1;
}
无向图的最小连通分量——Prim算法
此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。
图的所有顶点集合为VV;初始令集合u={s},v=V−uu={s},v=V−u;
在两个集合u,vu,v能够组成的边中,选择一条代价最小的边(u0,v0)(u0,v0),加入到最小生成树中,并把v0v0并入到集合u中。
重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。
class Solution {
public:
using rhs = pair<int, int>;
int minimumCost(int n, vector<vector<int>>& connections) {
vector<vector<rhs>> edge(n+1);
for(auto x : connections){
int a = x[0];
int b = x[1];
int w = x[2];
edge[a].push_back(make_pair(w, b));
edge[b].push_back(make_pair(w, a));
}
priority_queue<rhs, vector<rhs>, greater<rhs>> m_que;
m_que.push(make_pair(0, 1));
vector<bool> used(n+1, false);
int res = 0;
int cnt = 0;
while(m_que.size()){
auto top = m_que.top();
m_que.pop();
int cost = top.first;
int b = top.second;
if(used[b]){
continue;
}
used[b] = true;
res += cost;
cnt++;
for(auto x : edge[b]){
int y = x.second;
int w = x.first;
if(!used[y]){
m_que.push(make_pair(w, y));
}
}
}
if(cnt == n)
return res;
return -1;
}
};
版权声明:本文为qq_44700810原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。