You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.5 KiB

2 years ago
#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;
}