[hiho 14]并查集

题目描述

并查集,顾名思义有两个操作:合并和查询。

并就是把两个集合合并到一起。

查就是查询两个节点是否属于同一个集合。

每个节点有一个父节点。一个集合内存在一个唯一的根,判断根的条件就是节点的父节点是不是该节点本身。

合并操作就是把一个集合的根接到另一个集合的根上。

image

而查询操作就是找两个对象是否有同一个根。

查询过程中可以顺便进行路径压缩以优化后续查询:即让查找路径上所有节点的父节点直接等于根节点。

image

 

#include <iostream>
#include <algorithm>
#include <cstring>

#define MAX 200005

using namespace std;

int root[MAX];
char names[MAX][50];

unsigned int BKDRHash(char *str)
{
    unsigned int seed = 131;
    unsigned int hash = 0;

    while (*str)
    {
        hash = hash * seed + (*str++);
    }

    return (hash & 0x7FFFFFFF) % MAX;
}

int get_index(char *str) {
	int res = BKDRHash(str);
	while (strlen(names[res]) != 0 && strcmp(str, names[res])) {
		res++;
		res %= MAX;
	}
	if (strlen(names[res]) == 0) {
		strcpy(names[res], str);
	}
	return res;
}

int get_root(int a) {
	if (root[a] == -1) root[a] = a;
	if (a != root[a]) {
		root[a] = get_root(root[a]);
	}
	return root[a];
}

int main() {
	int n;
	int op;
	char s1[50], s2[50];
	int a, b;
	memset(root, -1, sizeof(root));
	cin >> n;
	while (n--) {
		cin >> op >> s1 >> s2;
		a = get_index(s1);
		b = get_index(s2);
		if (op == 0) {
			int fa = get_root(a), fb = get_root(b);
			root[fa] = fb;
		} else {
			int fa = get_root(a), fb = get_root(b);
			if (fa == fb) {
				cout << "yes" << endl;
			}
			else {
				cout << "no" << endl;
			}
		}
	}
	return 0;
}

转载于:https://www.cnblogs.com/xblade/p/4483306.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值