1.定义
prime算法是按照点与点之间的最小权值逐次将点加入到生成树中,而Kruskal算法则是按照每条边的长度依次排序,将最短的边中对应的点加入到最小生成树中,最小生成树的用并查集来表示。
1.Kruskal算法是以 边 为基础,每次从 边 集合中寻找最小的边(不管两个顶点属于V还是Vnew),然后判断该边的两个顶点是否同源(属于同一个连通分量)。 2.Kruskal需要对所有的边进行排序,然后从小到大,依次遍历每条边,同时判断每条边是否同源,如果同源,跳过;如果不同源,将两个连通分量合并,直到所有顶点属于同一个连通分量,算法结束。2.代码实现
class Solution {
public:
int minCostConnectPoints(vector<vector<int>>& points) {
vector<vnode>vlist;
for (int i = 0; i < points.size(); i++) {
for (int j = i + 1; j < points.size(); j++) {
//把所有点和边的组合加入到vlist中
vlist.push_back({ i,j,abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]) });
}
}
//按照边的最小序进行排序
sort(vlist.begin(), vlist.end(), [](vnode a, vnode b) {
return a.length < b.length;
});
ufs t(points.size());
for (auto x : vlist) {
t.merge(x.point1, x.point2, x.length);
if (t.get_count() == 1) {
return t.get_length();
}
}
return 0;
}
struct vnode {
int point1;
int point2;
int length;
};
//并查集
class ufs {
public:
ufs(int n):parent(vector<int>(n)),count(n),rank(vector<int>(n,0)) {
for (int i = 0; i < parent.size(); i++) {
parent[i] = i;
}
}
int find(int value){
if (parent[value] != value) {
return find(parent[value]);
}
else {
return value;
}
}
void merge(int point1,int point2,int length) {
if (find(point1) != find(point2)) {
if (rank[point2] > rank[point1]) {
swap(point1, point2);
}
parent[find(point2)] = find(point1);
rank[point1]++;
count--;
this->length += length;
// cout<<count<<" "<<length<<endl;
}
}
int get_count() { return count; }
int get_length() { return length; }
private:
vector<int>parent;
vector<int>rank;
int count;
int length = 0;
};
};