代码随想录算法训练营第五十五天|图论part5

发布于:2025-07-31 ⋅ 阅读:(20) ⋅ 点赞:(0)

并查集理论基础

初始化:

void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
    }
}

寻根:

// 并查集里寻根的过程
int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
}

判断u跟v是否同根

// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {
    u = find(u);
    v = find(v);
    return u == v;
}

加入并查集:

// 将v->u 这条边加入并查集
void join(int u, int v) {
    u = find(u); // 寻找u的根
    v = find(v); // 寻找v的根
    if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
    father[v] = u;
}

按秩合并的代码如下:
 

int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构
vector<int> rank = vector<int> (n, 1); // 初始每棵树的高度都为1

// 并查集初始化
void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
        rank[i] = 1; // 也可以不写
    }
}
// 并查集里寻根的过程
int find(int u) {
    return u == father[u] ? u : find(father[u]);// 注意这里不做路径压缩
}

// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {
    u = find(u);
    v = find(v);
    return u == v;
}

// 将v->u 这条边加入并查集
void join(int u, int v) {
    u = find(u); // 寻找u的根
    v = find(v); // 寻找v的根

    if (rank[u] <= rank[v]) father[u] = v; // rank小的树合入到rank大的树
    else father[v] = u;

    if (rank[u] == rank[v] && u != v) rank[v]++; // 如果两棵树高度相同,则v的高度+1,因为上面 if (rank[u] <= rank[v]) father[u] = v; 注意是 <=
}

寻找存在的路径

文章讲解:代码随想录

题目链接:107. 寻找存在的路径

思路:

并查集裸题,考察两个节点的连通性

#include <iostream>
#include <vector>
using namespace std;
int n=101;
vector<int>father(n,0);

void init(){
    for(int i=0;i<n;i++){
        father[i]=i;
    }
}

int find(int x){
    if(father[x]==x)return x;
    else return father[x]=find(father[x]);
}
void join(int u,int v){
    u=find(u);
    v=find(v);
    if(u==v) return;
    father[v]=u;
}
bool isSame(int u,int v){
    u=find(u);
    v=find(v);
    return u==v;
}



int main(){
    int n,m;
    cin>>n>>m;
    init(); // 初始化并查集    上面只是定义 这里要调用
    for(int i=0;i<m;i++){
        int s,t;
        cin>>s>>t;
        join(s,t);     //这里构建并查集
    }
    int source,dest;
    cin>>source>>dest;
    bool ans=isSame(source,dest);
    if(ans)cout<<1;
    else cout<<0;

}

网站公告

今日签到

点亮在社区的每一天
去签到