|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
//此题,数据范围太大,必须离散化处理(这是策略二,还需要一种简单版本的离散化)
|
|
|
//关注一下数据范围,是有10的9次方那么大,如果开一个10的9次方大的fa数组的话,空间肯定超限,超限就凉凉
|
|
|
int t;//表示需要判定的问题个数
|
|
|
int n;//表示该问题中需要被满足的约束条件个数
|
|
|
int x; //第一个数
|
|
|
int y; //第二个数
|
|
|
int e; //是否相等,1相等,0不相等
|
|
|
|
|
|
const int N = 1000010;
|
|
|
int fa[N];
|
|
|
|
|
|
//要深入理解这个递归并压缩的过程
|
|
|
int find(int x) {
|
|
|
if (fa[x] != x) fa[x] = find(fa[x]);
|
|
|
return fa[x];
|
|
|
}
|
|
|
|
|
|
//加入家族集合中
|
|
|
void join(int c1, int c2) {
|
|
|
int f1 = find(c1), f2 = find(c2);
|
|
|
if (f1 != f2)fa[f1] = f2;
|
|
|
}
|
|
|
|
|
|
//先记录,再离散化
|
|
|
struct Node {
|
|
|
int x, y, e;
|
|
|
} a[N];
|
|
|
|
|
|
//先处理相等,再处理不相等的,这个排序器是用来决定相等优先的
|
|
|
bool cmp(const Node &a, const Node &b) {
|
|
|
return a.e > b.e;
|
|
|
}
|
|
|
|
|
|
int main() {
|
|
|
cin >> t;
|
|
|
while (t--) {
|
|
|
cin >> n;
|
|
|
//初始化
|
|
|
memset(a, 0, sizeof a);
|
|
|
memset(fa, 0, sizeof fa);
|
|
|
//录入+离散化
|
|
|
vector<int> alls; // 存储所有待离散化的值
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
cin >> a[i].x >> a[i].y >> a[i].e;
|
|
|
alls.push_back(a[i].x), alls.push_back(a[i].y);
|
|
|
}
|
|
|
// 将所有值排序
|
|
|
sort(alls.begin(), alls.end());
|
|
|
// 去掉重复元素
|
|
|
alls.erase(unique(alls.begin(), alls.end()), alls.end());
|
|
|
// 二分求出x对应的离散化的值
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
a[i].x = lower_bound(alls.begin(), alls.end(), a[i].x) - alls.begin();
|
|
|
a[i].y = lower_bound(alls.begin(), alls.end(), a[i].y) - alls.begin();
|
|
|
}
|
|
|
|
|
|
//排序,先处理相等的,再处理不相等的.这样才能保证亲戚都认领完了,再找出矛盾。
|
|
|
sort(a + 1, a + 1 + n, cmp);
|
|
|
//初始化并查集
|
|
|
for (int i = 1; i <= alls.size(); i++) fa[i] = i;
|
|
|
|
|
|
bool success = true;
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
if (a[i].e == 1) join(a[i].x, a[i].y);
|
|
|
else {
|
|
|
int f1 = find(a[i].x), f2 = find(a[i].y);
|
|
|
if (f1 == f2) {
|
|
|
success = false;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (success) cout << "YES" << endl;
|
|
|
else cout << "NO" << endl;
|
|
|
}
|
|
|
return 0;
|
|
|
} |