先说一下各个数组的含义:
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;
}