链接:https://ac.nowcoder.com/acm/contest/904/B
来源:牛客网
题目描述
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
解题思路:
就是并查集模板,但是名字是字符串不好处理,用了unordered_map函数
#include <bits/stdc++.h>
using namespace std;
#define N 20020
map<string, int> name;
int f[N];
char str1[20], str2[20];
int getf(int v)
{
if(f[v]==v)
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
void merge(int u, int v)
{
int t1, t2;
t1=getf(v);
t2=getf(u);
if(t1!=t2)
f[t2]=t1;
}
int main()
{
int i, n, m, u, v, op, book;
scanf("%d%d",&n, &m);
for(i=1; i<=n; i++)
{
scanf("%s", str1);
name[str1]=i;
}
for(i=1; i<=n; i++)
f[i]=i;
while(m--)
{
scanf("%d %s %s", &op, str1, str2);
book=0;
if(op==1)
merge(name[str1], name[str2]);
if(op==2)
{
if(getf(f[name[str1]])==getf(f[name[str2]]))
printf("1\n");
else
printf("0\n");
}
}
return 0;
}