当前位置: 首页 > news >正文

代码随想录-训练营-day46

今天我们来学习并查集的使用,用一个具体的例题来做:

107. 寻找存在的路径 (kamacoder.com)

#include<iostream>
#include<vector>
using namespace std;
vector<int> father(101);
int n;
void init(){
    for(int i=1;i<=n;++i)father[i]=i;
}
int find(int u){
    return u==father[u]?u:father[u]=find(father[u]);
}
bool isSame(int u,int v){
    u=find(u);
    v=find(v);
    return u==v;
}
void join(int u,int v){
    u=find(u);
    v=find(v);
    if(u==v)return;
    father[v]=u;
}
int main(){
    int m,s,t;
    cin>>n>>m;
    init();
    for(int i=0;i<m;++i){
        cin>>s>>t;
        join(s,t);
    }
    int source,destination;
    cin>>source>>destination;
    if(isSame(source,destination)){
        cout<<1<<endl;
        return 0;
    }
    else{
        cout<<0<<endl;
        return 0;
    }
}

事实上,这就是一个并查集的模板题,我们不妨把并查集的模板放上来:

int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构

// 并查集初始化
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是否找到同一个根
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;
}

总的来说我们有四个函数:初始化,查找,判断是否同根,联合。初始化只是先构建一个大体的映射关系,而查找就是进行一个路径压缩,如何理解呢?准确地说就是去找根的一个过程,我们判断u和father[u]是否相等,如果相等说明u本身就是一个根节点,可如果不是,说明u的根节点是一个其他节点,那这个时候我们就要去找u的根节点了:我们向上一层,去找father[u]的根节点并形成递归;

判断同根很好理解,最后的联合则是先找到两个节点的根节点,如果发现两个根相同说明二者在同一个集合中,不然我们就让u成为v的父节点,也就是说让v的集合全部放在u下面,形成v->u的路径。

一般来说,我们会在针对判断两个点是否在同一个集合里的题使用并查集,尤其是判断比如我们的图论题中两个点是否有存在路径。

相关文章:

  • ES语法学习
  • neo4j-解决neo4j网页版打不开
  • HPC超算系列3——新手指南2
  • 基于Asp.net的度假村管理系统
  • 【弹性计算】异构计算云服务和 AI 加速器(二):适用场景
  • 快乐数 力扣202
  • Windows下安装kafka
  • WebGL 深度解析:从原理到实践的全方位指南
  • ClusterIP、Headless Service 和 NodePort 的比较
  • 整理了一下网络编程中TCP的状态
  • 小程序 wxml 语法 —— 38 setData() - 修改数组类型数据
  • 如何在vscode里像typora那样插入图片?
  • Django Form 组件
  • K8S学习之基础十八:k8s的灰度发布和金丝雀部署
  • Python使用入门(一)
  • 从0开始的操作系统手搓教程27:下一步,实现我们的用户进程
  • C++第十节:map和set的介绍与使用
  • Ubuntu 22.04 LTS 入门教学文档
  • LeetCode1137 第N个泰波那契数
  • 每日一练之移除链表元素
  • 免费wap自助建站网站/网络销售靠谱吗
  • 领先的手机网站设计/网站软文代写
  • 更新公司网站内容需要/外贸建站服务推广公司
  • 企业做网站的费用计入什么科目/杭州网站seo外包
  • 传奇大气网站模板免费下载/如何推广一个项目
  • 网站建设犭金手指a排名12/网站优化排名易下拉霸屏