哈希表 + 离散化 + 并查集 50 pts (清空了的)
查看原帖
哈希表 + 离散化 + 并查集 50 pts (清空了的)
742157
ZYK_luogu楼主2023/8/11 19:14

先说一下各个数组的含义:

vector<int> linker; // 哈希表用的
a[N];  有哪些数的出现
a1[N] & backup[N];// 均为临时数组(或者说备份数组
b[N]; / 离散化完的数组
fa[N]; // 并查集专用
act[N][3]; // 记录有哪些操作

然后是完整代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1000010, mod = 23333;
int T, n, act[N][3];
int a[N], a1[N], backup[N], b[N], cnt = 0, fa[N];
vector<int> linker[mod + 2];
inline void init() {
	memset(backup, 0, sizeof backup);
	memset(a1, 0, sizeof a1);
	memset(a, 0, sizeof a);
	memset(b, 0, sizeof b);
	for(int i = 1; i <= n; i ++)
		fa[i] = i;
	for(int i = 0; i < mod + 2; i ++)
		linker[i].clear();
}
inline void insert(int x) {
	int hash = x % mod;
	for(int i = 0, siz = linker[hash].size(); i < siz; i ++)
		if(linker[hash][i] == x)
			return;
	linker[hash].push_back(x);
}
inline void get_nums() {
	for(int i = 0; i < mod + 2; i ++)
		for(int j = 0, siz = linker[i].size(); j < siz; j ++)
			a[++ cnt] = linker[i][j];
}
inline void ls() {
	for(int i = 1; i <= n; i ++)
		backup[i] = a[i];
	sort(backup + 1, backup + n + 1);
	for(int i = 1; i <= n; i ++)
		b[i] = lower_bound(backup + 1, backup + n + 1, a[i]) - backup;
}
int find(int x) {
	if(fa[x] == x) return x;
	else return fa[x] = find(fa[x]);
}
int get_val(int x) {
	return lower_bound(a1 + 1, a1 + cnt + 1, x) - a1;
}
inline int sol() {
	init();
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		insert(x), insert(y);
		act[i][0] = z, act[i][1] = x, act[i][2] = y;
	}
	get_nums(), ls();
	for(int i = 1; i <= cnt; i ++) a1[i] = a[i];
	sort(a1 + 1, a1 + cnt + 1);
	for(int i_ = 1; i_ <= n; i_ ++) {
		int i = get_val(act[i_][1]), j = get_val(act[i_][2]), e = act[i_][0];
		if(e == 1) fa[find(i)] = find(j);
		else {
			if(find(i) == find(j))
				return 0;
		}
	}
	return 1;
}
int main() {
	scanf("%d", &T);
	while(T --) 
		printf("%s\n", sol() ? "YES" : "NO");
	return 0;
}
2023/8/11 19:14
加载中...