• 【每日一题(并查集,字符串)--8.9】


    前言

    • 并查集
    1. 将两个集合合并
    2. 询问两个元素是否在一个集合当中

    问题1:如何判断树根?if(p[x]==x)
    问题2;如何求x的集合编号?while(p[x]!=x)x = p[x];
    问题3:如何合并两个集合:px是x的集合编号,py是y的集合编号。p[x]=y。
    在这里插入图片描述

    基本原理: 每个集合用一棵树来表示

    一中校运会之百米跑

    题目背景

    在一大堆秀恩爱的 ** 之中,来不及秀恩爱的苏大学神踏着坚定(?)的步伐走向了 100 100 100 米跑的起点。这时苏大学神发现,百米赛跑的参赛同学实在是太多了,连体育老师也忙不过来。这时体育老师发现了身为体育委员的苏大学神,便来找他帮忙。

    可是苏大学神需要热身,不然跑到一半就会抽(筋)、于是他就找到了你。。。如果你帮助体育老师解决了问题,老师就会给你 5 5 5 个积分。

    题目描述

    假设一共有 N N N 2 ≤ N ≤ 2 × 1 0 4 2\leq N\leq 2\times 10^4 2N2×104)个参赛选手。(尼玛全校学生都没这么多吧)

    老师会告诉你这 N N N 个选手的名字。

    接着会告诉你 M M M 1 ≤ M ≤ 1 0 6 1\leq M\leq 10^6 1M106)句话,即告诉你学生 A 与学生 B 在同一个组里。

    如果学生 A 与学生 B 在同一组里,学生 B 与学生 C 也在同一组里,就说明学生 A 与学生 C 在同一组。

    然后老师会问你 K K K 1 ≤ K ≤ 1 0 6 1\leq K\leq 10^6 1K106)句话,即学生 X 和学生 Y 是否在同一组里。

    若是则输出 Yes.,否则输出 No.

    输入格式

    第一行输入 N N N M M M

    接下来 N N N 行输入每一个同学的名字。

    再往下 M M M 行每行输入两个名字,且保证这两个名字都在上面的 N N N 行中出现过,表示这两个参赛选手在同一个组里。

    再来输入 K K K

    接下来输入 K K K 个体育老师的询问。

    输出格式

    对于每一个体育老师的询问,输出 Yes.No.

    样例 #1

    样例输入 #1

    10 6
    Jack
    Mike
    ASDA
    Michel
    brabrabra
    HeHe
    HeHE
    papapa
    HeY
    Obama
    Jack Obama
    HeHe HeHE
    brabrabra HeHe
    Obama ASDA
    papapa Obama
    Obama HeHE
    3
    Mike Obama
    HeHE Jack
    papapa brabrabra
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    样例输出 #1

    No.
    Yes.
    Yes.
    
    • 1
    • 2
    • 3

    思路

    但是,还有一个更好用的东西:STL中的map
    直接建立一个由字符串到字符串的映射代替数组。然后就是把模板复制上去

    //并查集模板
    int p[N];//存储每个点的祖宗节点
    int find(x){
    	if(p[x]!!=x) p[x]=find(p[x])
    	return p[x];
    }
    
    //初始化
    for(int i =1;i<=n;i++)p[i]=i;
    
    //合并a 和b 的所在两个集合如果不存在
    p[find(a)]= find(b);
    /*
    等同于 x=find(a),x2=find(b);
    if(x!=x2)p[x]=x2;
    */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    推导过程 :)
    p[5]=5,p[3]=3;
    如果是M操作的话那么就将集合进行合并,合并的操作是:
    p[3]=p[5]=5;
    所以3的祖宗节点便成为了5
    此时以5为祖宗节点的集合为{5,3}
    如果要将p[9]=9插入到p[3]当中,应该找到3的祖宗节点,
    然后再把p[9]=9插入其中,所以p[9]=find(3);(find()函数用于查找祖宗节点)
    也可以是p[find(9)]=find(3),因为9的节点本身就是9
    此时以5为祖宗节点的集合为{5,3,9};
    如果碰到多个数的集合插入另一个集合当中其原理是相同的

    #include
    using namespace std;
    mapmp;
    string find(string x)
    {
        if(mp[x]!=x)mp[x]=find(mp[x]);
        return mp[x];
    }
    
    int  main(){
        int n,m;
        cin>>n>>m;
        for(int i=0;i>a;
            mp[a]=a;
        }
        for(int i = 0;i>a>>b;
            mp[find(a)]=find(b);
        }
        int k ;
        cin>>k;
        while(k--){
            string q,p;
            cin>>q>>p;
            
            if(find(q)==find(p))puts("Yes.");
            else puts("No.");
        }
        return 0;
      
    }
    ```![在这里插入图片描述](https://img-blog.csdnimg.cn/7832692807524f7e809bbb71b96f3ec8.png)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    C++:STL(标准模板库)
    多线程环境下的单例模式
    vscode 无法激活conda虚拟环境
    C. Jumping on Tiles codeforces1729C
    李沐动手学深度学习V2-Encoder-Decoder编码器和解码器架构
    mulesoft Module 8 quiz 解析
    知识分享应用-后端代码从0构建
    字符函数和字符串函数(C语言)
    WIN10 驱动开发环境从0搭建 (驱动开发必看)
    视频分析:走路看手机行为
  • 原文地址:https://blog.csdn.net/m0_53142039/article/details/126240741