并查集模板与在Kruskal中的没应用
背背佳冰茶机模板
class Solution {
private:
vector<int> root;
int branch_num;
//root初始化
void UnionFind(int size) {
root.resize(size);
for (int i = 0; i < size; i++) {
root[i] = i;
}
branch_num=size;
}
//寻找x的根节点
int find(int x) {
if (x == root[x]) {
return x;
}
return root[x] = find(root[x]);
}
//connect x->y
void merge(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
root[rootY] = rootX;
branch_num--;
}
}
//x与y是否连通
bool connected(int x, int y) {
return find(x) == find(y);
}
在最小连通片中的应用
public:
int findCircleNum(vector<vector<int>>& isConnected) {
unordered_set<int> root;
int num=isConnected.size();
UnionFind(num);
for(int i=0;i<num;i++){
for(int j=i+1;j<num;j++){
if(isConnected[i][j]){
merge(i,j);
}
}
}
return branch_num;
}
};
Prim算法(没用)
struct Node{
int u,v,val;
Node(int x=0,int y=0,int dis=0):u(x),v(y),val(dis){}
};
bool operator<(Node a, Node b){
return a.val>b.val;
}//这玩意在priority的自排序中使用
class Solution {
public:
int minCostConnectPoints(vector<vector<int>>& points) {
int n=points.size();
priority_queue<Node> que;
vector<int> vis(n,0);
for(int j=1;j<n;j++){
int dis=abs(points[j][0]-points[0][0])+abs(points[j][1]-points[0][1]);
que.emplace(Node(0,j,dis));
}
int res=0,count=n-1;
vis[0]=1;
while(!que.empty()&&count>0){
auto e=que.top();
que.pop();
int x=e.u,y=e.v;
int cost=e.val;
if(!vis[y]){
res+=cost;
vis[y]=1;
for(int i=0;i<n;i++){
if(!vis[i]){
int dis=abs(points[i][0]-points[y][0])+abs(points[i][1]-points[y][1]);
que.emplace(Node(y,i,dis));
}
}
count--;
}
}
return res;
}
};
//用优先队列代替排序比较,social
Kruskal算法
伪代码:
set=已加入的顶点
将点点间按长度进优先队列(vector<int>)element={length,a_order,b_order}
merge(top.a_order,b_order);
while(num<=n-1)
if(find(top.a_order)!=find(top.b_order))
merge(top.a_order,b_order)
num++
sum+=top.length
priority_queue.pop()
愿偿少年泪,犹趁未老时!
本文来自博客园,作者:clfire,转载请注明原文链接:https://www.cnblogs.com/sky1water/p/16720542.html