P3367 并查集 模板题

[复制链接]
发表于 2026-3-30 17:09:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
P3367 并查集 模板题

🔗 原题链接
📌 标题形貌

标题

现在有 \(n\) 个元素,分为多少个聚集。须要支持两种操纵:

  • 归并操纵 (\(z=1\)):将 \(x\) 和 \(y\) 地点的聚集归并为一个聚集
  • 查询操纵 (\(z=2\)):查询 \(x\) 和 \(y\) 是否在同一个聚会合
输入格式


  • 第一行:\(n, m\)(\(n\) 个元素,\(m\) 次操纵)
  • 接下来 \(m\) 行:每行三个整数 \(z, x, y\)

    • 若 \(z=1\):归并 \(x, y\) 地点聚集
    • 若 \(z=2\):查询 \(x, y\) 是否同属一个聚集

输特别式


  • 对每个查询操纵(\(z=2\)),输出 Y 或 N
束缚条件


  • \(1 \leq n \leq 10^5\)
  • \(1 \leq m \leq 10^5\)
  • \(1 \leq x, y \leq n\)
💡 焦点思绪
  1. 每个点都是一颗树的节点,
  2. 相同集合的点的根相同,
  3. 指向同一个数
  4. 并查集 = 树结构 + 找根(find) + 合并(union) + 路径压缩优化
复制代码
📋 模板步调
  1. 初始化树
复制代码
  1.    rep(i,1,n+1) fa[i]=i;//每个节点的fa都是自己
  2.     每个循环输入x,y
  3.     先找到他们各自的根
  4.     x=find(x),y=find(y);
  5.     如果合并,把y的根节点指向x的根节点,
  6.     x=fa[y];
  7.     否则判断两者的根是否相同
  8.    
  9.     找根节点find函数实现
  10. ##  优化点
  11.     使用递归可将沿路的的节点的父节点都指向根节点,
  12.     使树的深度接近常数级,提升后续查询效率
  13.     int find(int x){
  14.         if(fa[x]==x) return x;
  15.         return fa[x]=find(fa[x]);
  16.     }
复制代码
代码实现

完备代码

[code]    const int N=2e5+5;    int a[N];        int find(int x){        if(x==fa[x]) return x;        return fa[x]=find(fa[x]);    }    void solve(){        int n,m;        cin>>n>>m;        rep(i,1,n+1) fa=i;            int x,y,z;        while(m--){            cin>>z;            x=find(x);            y=find(y);            if(z==1){                x=fa[y];            }            else {                if(x==y) cout
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表