并查集模板题(stl 中map的运用)

本文介绍了一个使用并查集算法解决亲戚关系查询问题的编程实例。通过字符串映射到唯一标识符的方式,实现了对大规模亲戚网络的高效查询。代码示例展示了如何初始化并查集,以及如何进行亲戚关系的合并与查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DongDong认亲戚
DongDong每年过春节都要回到老家探亲,然而DongDong记性并不好,没法想起谁是谁的亲戚(定义:若A和B是亲戚,B和C是亲戚,那么A和C也是亲戚),她只好求助于会编程的你了。
输入描述:
第一行给定n,m表示有n个人,m次操作

第二行给出n个字符串,表示n个人的名字分别是什么(如果出现多个人名字相同,则视为同一个人)(保证姓名是小写字符串)

接下来m行,每行输入一个数opt,两个字符串x,y

当opt=1时,表示x,y是亲戚

当opt=2时,表示询问x,y是否是亲戚,若是输出1,不是输出0

数据范围:1<=n,m<=20000,名字字符长度小等于10
输出描述:
对于每个2操作给予回答
示例1
输入

4 4
chen lin yi cheng
2 chen lin
1 chen lin
1 yi lin
2 yi lin
输出

0
1
ps:一看就是并查集模板题,但不同的是,一般的并查集题都是具体的数字进行并查操作,而这道题是用字符串进行操作,很容易想到把每个字符串当成某个确定的数字,再进行操作,然后果断一个TLE教做人,后来我又想到用set来存,发现还是同样的问题没解决,最后才知道可以用map来存名字,map就是一种映射关系,就可以把字符串模拟成数组(很像JavaScript里面的自定义数组)那种,进行并与查的操作,具体看代码。

我的垃圾 代码

#include<bits/stdc++.h>
using namespace std;
unordered_map<string, string> root; //存放每个人,以及对应的祖先,其跟map的区别是可以存相同的键,用法都大致相同
string GetRoot(string node){  //找祖先
    if (node == root[node])
        return node;
    return root[node] = GetRoot(root[node]);
}
void Union(string person1, string person2){//将两人合并为亲戚
    string p1 = GetRoot(person1);
    string p2 = GetRoot(person2);
    root[p2] = p1;
}
bool SameRoot(string person1, string person2){//查找是否是亲戚
    string p1 = GetRoot(person1);
    string p2 = GetRoot(person2);
    return p1 == p2;
}
int main(){
    int n,op,m;
    string person1, person2;
    cin >> n>>m;
    for(int i=0;i<n;i++){
        cin>>person1;
        root[person1]=person1;
    }
    while (m--){
       cin>>op>>person1>>person2;
        if (op ==1 ){
            Union(person1, person2);
        }
        else{
            if (SameRoot(person1, person2))
                printf("1\n");
            else
                printf("0\n");
        }
    }
    return 0;
}

神仙的代码,orz,这也太nb了,菜鸡已经看呆了

#include<bits/stdc++.h>
using namespace std;
unordered_map<string,string>M;
string t,tt;
int n,m,o,i;
string find(string x){
      return x==M[x]?x:M[x]=find(M[x]);
}
int main()
{
    cin>>n>>m;
    for(i=0;i<n;i++)
    cin>>t,M[t]=t;
    for(i=0;i<m;i++)
    cin>>o>>t>>tt,o==1?(M[find(tt)]=find(t),0):(puts(find(t)==find(tt)?"1":"0"));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值