牛客练习赛47 B:DongDong认亲戚 (并查集)

链接: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
");
			else
				printf("0
");
		}
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/zyq1758043090/p/11852679.html