• 【数据结构:并查集】


     “你只看见我渺小的身躯,却没有看到我心中的广阔森林。”


    基础知识


    并查集常见的两个操作:

    • 合并(Union):把两个不相交的集合合并为一个集合。
    • 查询(Find):查询两个元素是否在同一个集合中。

    并查集是一种用于处理一些不相交的集合的合并查询问题的树形数据结构,能够将两个集合合并或者查询某个元素处于哪个集合中


    模板题:洛谷P3367 【模板】并查集

    题目描述

    如题,现在有一个并查集,你需要完成合并和查询操作。

    输入格式

    第一行包含两个整数 N,M ,表示共有 N 个元素和 M 个操作。

    接下来 M 行,每行包含三个整数 Zi​ , Xi ​, Yi​ 。

    当 Zi​=1 时,将 Xi​ 与 Yi​ 所在的集合合并。

    Zi​=2 时,输出 Xi​ 与 Yi​ 是否在同一集合内,是的输出 Y ;否则输出 N 。

    输出格式

    对于每一个 Zi​=2 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。

    输入输出样例

    输入 #1

    4 7
    2 1 2
    1 1 2
    2 1 2
    1 3 4
    2 1 4
    1 2 3
    2 1 4

    输出 #1

    N
    Y
    N
    Y
    

    说明/提示

    对于 30% 的数据, N≤10,M≤20。

    对于70% 的数据,N≤100,M≤10^3。

    对于 100% 的数据,1≤N≤10^4, 1≤M≤2×10^5,1≤Xi​,Yi​≤NZi​∈{1,2}。


    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int z,x,y,fa[100000];
    6. int find(int x) //查找根节点
    7. {
    8. if(x==fa[x]) return x; //如果父节点已经是根节点,返回该值
    9. else
    10. {
    11. fa[x]=find(fa[x]); //将父节点设为根节点
    12. return fa[x]; //返回父节点
    13. }
    14. }
    15. /*现在常写:
    16. int find(int x)
    17. {
    18. if(x==fa[x]) return x;
    19. return fa[x]=find(fa[x]);
    20. }
    21. */
    22. void add(int x,int y) //将两个元素合并成一个集合
    23. {
    24. fa[find(y)]=find(x); //将两者中的其中一个元素设为另一个元素的父节点
    25. }
    26. int main()
    27. {
    28. int n,m;
    29. scanf("%d %d",&n,&m);
    30. for(int i=1;i<=n;++i)
    31. {
    32. fa[i]=i; //集合初始化,最初的所有元素的父节点都是自己
    33. }
    34. for(int i=1;i<=m;++i)
    35. {
    36. scanf("%d %d %d",&z,&x,&y);
    37. if(z==1) add(x,y); //合并操作
    38. else
    39. {
    40. if(find(x) == find(y)) //比较根节点是否相同
    41. printf("Y\n"); //相同则在一个集合中
    42. else printf("N\n");
    43. }
    44. }
    45. return 0;
    46. }

    相关练习:1.洛谷P1536 村村通 

    注意:当n==0时才能结束程序 

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int maxn=1e7+5;
    7. int fa[maxn];
    8. inline int find(int x)
    9. {
    10. if(x == fa[x]) return x;
    11. return fa[x] = find(fa[x]);
    12. }
    13. int main()
    14. {
    15. int n,m,x,y;
    16. while(cin>>n&&n!=0)
    17. {
    18. int ans=0;
    19. scanf("%d",&m);
    20. for(int i=1;i<=n;++i)
    21. {
    22. fa[i]=i;
    23. }
    24. for(int i=1;i<=m;++i)
    25. {
    26. scanf("%d%d",&x,&y);
    27. int p=find(x);
    28. int q=find(y);
    29. if(p==q) continue;
    30. fa[q]=p;
    31. }
    32. for(int i=1;i<=n;++i)
    33. {
    34. if(fa[i]==i) ans++;
    35. //自己的父亲等于自己本身,找到某个根的相关节点
    36. }
    37. printf("%d\n",ans-1);
    38. }
    39. return 0;
    40. }

  • 相关阅读:
    pytorch深度学习实战19
    EasyExcel综合课程实战
    【数学建模学习笔记【集训十天】之第七天】
    npy和npz里的图片分解(格式讲解)!超级清晰版本
    快速清除PPT缓存文件或C盘隐藏大文件
    点云从入门到精通技术详解100篇-基于几何特征的三维点云配准(续)
    从头训练一个神经网络!教它学会莫奈风格作画!
    链表经典面试题之一讲
    蓝牙技术|蓝牙轻松部署物联网项目,智能照明利用蓝牙特性快速发展
    论有一个面板小程序物料库的重要性!开发效率提升两三倍
  • 原文地址:https://blog.csdn.net/gzkeylucky/article/details/122993933