小工具知识网

当前位置: 首页 > 行业知识 > 【算法】并查集

行业知识

【算法】并查集

2026-11-05 07:42:26 来源:互联网转载

目录

  • 并查集简介
  • 主要思想
  • 模板代码
  • 进阶题目
    • 样例
      • 样例输入
      • 样例输出
      • 样例解释
      • 解决思路
      • 代���

        并查集简介

        并查集是一种常见的数据结构

        主要用于解决"亲戚"问题,如 x x x 的亲戚为 y y y, y y y 的亲戚为 z z z,那么我们说 x x x 也是 z z z 的亲戚

        主要思想

        我们定义一个数组fa[x]表示 x x x 的父亲节点

        我们定义一种函数find(x)查询 x x x 所属路径的根节点

        有什么用呢?

        当 x x x 与 y y y 形成亲戚关系是,我们令 y y y 为 x x x 的祖先(即 find(x) )的父亲

        最终会有亲戚关系的会形成如下的一条链

        所以 x x x, y y y, z z z, f f f 互为亲戚

        此时, f i n d ( x ) find(x) find(x) 为 f f f

        那么我们可以根据 find() 函数是否相同判断两个人是否为亲戚

        还有一个东西叫路径压缩

        如找 f i n d ( x ) find(x) find(x) 时,可以把 x x x 的父亲直接链接到祖先

        如图,红线指向压缩后的父亲

        路径压缩后时间复杂度将会减少,不会一次一次慢慢找了

        模板代码

        题目链接:P1551 亲戚

        #include#define ll long long#define endl '\n'using namespace std;int n,m,p,x,y,f[5005];int find(int x){ //找x的祖先if(f[x]==x) return x; else return f[x]=find(f[x]); // 路径压缩}int main(){scanf("%d%d%d",&n,&m,&p);for(int i=1;iscanf("%d%d",&x,&y);f[find(x)]=find(y); //x的祖先的父亲链接到y的祖先}for(int i=1;iscanf("%d%d",&x,&y);if(find(x)==find(y)) cout //并查集模板(找x的祖先)if(f[x]==x) return x;else return f[x]=find(f[x]); //路径压缩}int main(){scanf("%d%d",&n,&m);for(int i=1;icinc; scanf("%d%d",&x,&y);if(c=='F') //如果x于y为朋友关系f[find(x)]=find(y); //同模板代码else {f[find(x)]=find(y+n); //x的祖先与y的敌人相连f[find(x+n)]=find(y); //x的敌人的祖先于y的祖先相连}}for(int i=1;iif(a[find(i)]==0) ans++; //如果i的祖先所属的链没有出现,那么结果+1a[find(i)]=1; //i的祖先所属的链出现了,记录}printf("%d",ans);return 0;}

上一篇:宝塔面板替代方案详解,轻松上手,替代首选!

下一篇:揭秘网页鼠标特效设置秘籍,轻松打造炫酷交互体验!